diff --git a/src/java/com/threerings/parlor/tourney/client/TourneyService.java b/src/java/com/threerings/parlor/tourney/client/TourneyService.java
new file mode 100644
index 00000000..0f1f17d9
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/client/TourneyService.java
@@ -0,0 +1,49 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.client;
+
+import com.threerings.presents.client.Client;
+import com.threerings.presents.client.InvocationService;
+import com.threerings.presents.client.InvocationService.ConfirmListener;
+import com.threerings.presents.client.InvocationService.InvocationListener;
+
+/**
+ * Provides tourney management services for the particular tourney this
+ * service is attached to.
+ */
+public interface TourneyService extends InvocationService
+{
+ /**
+ * Handles a request to join the tourney.
+ */
+ public void join (Client caller, ConfirmListener listener);
+
+ /**
+ * Handles a request to leave the tourney.
+ */
+ public void leave (Client caller, ConfirmListener listener);
+
+ /**
+ * Handles a request to cancel the tourney.
+ */
+ public void cancel (Client caller, ConfirmListener listener);
+}
diff --git a/src/java/com/threerings/parlor/tourney/client/TourniesService.java b/src/java/com/threerings/parlor/tourney/client/TourniesService.java
new file mode 100644
index 00000000..585a6946
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/client/TourniesService.java
@@ -0,0 +1,38 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.client;
+
+import com.threerings.parlor.tourney.data.TourneyConfig;
+
+import com.threerings.presents.client.Client;
+import com.threerings.presents.client.InvocationService;
+
+/**
+ * Provices services for creating/modifying tournies.
+ */
+public interface TourniesService extends InvocationService
+{
+ /**
+ * Creates a new tourney.
+ */
+ public void createTourney (Client client, TourneyConfig config, ResultListener listener);
+}
diff --git a/src/java/com/threerings/parlor/tourney/data/EntryFee.java b/src/java/com/threerings/parlor/tourney/data/EntryFee.java
new file mode 100644
index 00000000..0afa5c35
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/data/EntryFee.java
@@ -0,0 +1,54 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.data;
+
+import com.samskivert.util.ResultListener;
+
+import com.threerings.crowd.data.BodyObject;
+
+import com.threerings.io.SimpleStreamableObject;
+
+/**
+ * Extensible entry fee class that specifies entry requirements for a tourney.
+ */
+public abstract class EntryFee extends SimpleStreamableObject
+{
+ /**
+ * Returns a description of the entry fee.
+ */
+ public abstract String getDescription ();
+
+ /**
+ * Checks if the user has the required entry fee.
+ */
+ public abstract boolean hasFee (BodyObject body);
+
+ /**
+ * Attempts to reserve the entry fee.
+ */
+ public abstract void reserveFee (BodyObject body, ResultListener listener);
+
+ /**
+ * Returns the entry fee.
+ */
+ public abstract void returnFee (BodyObject body);
+}
diff --git a/src/java/com/threerings/parlor/tourney/data/Participant.java b/src/java/com/threerings/parlor/tourney/data/Participant.java
new file mode 100644
index 00000000..830fb500
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/data/Participant.java
@@ -0,0 +1,66 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.data;
+
+import java.lang.Comparable;
+
+import com.threerings.util.Name;
+import com.threerings.io.SimpleStreamableObject;
+import com.threerings.presents.dobj.DSet;
+
+/**
+ * Contains information on a particular tourney participant.
+ */
+public class Participant extends SimpleStreamableObject
+ implements DSet.Entry, Comparable
+{
+ /** The username of the participant. */
+ public Name username;
+
+ // documentation inherited from interface DSet.Entry
+ public Comparable getKey ()
+ {
+ return username;
+ }
+
+ // documentation inherited from interface Comparable
+ public int compareTo (Object o)
+ {
+ Participant op = (Participant)o;
+ return username.compareTo(op.username);
+ }
+
+ // documentation inherited from interface Comparable
+ public boolean equals (Object other)
+ {
+ if (other instanceof Participant) {
+ return ((Participant) other).username.equals(username);
+ }
+ return false;
+ }
+
+ // documentation inherited
+ public String toString ()
+ {
+ return username.toString();
+ }
+}
diff --git a/src/java/com/threerings/parlor/tourney/data/Prize.java b/src/java/com/threerings/parlor/tourney/data/Prize.java
new file mode 100644
index 00000000..6d22af6a
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/data/Prize.java
@@ -0,0 +1,35 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.data;
+
+import com.threerings.io.SimpleStreamableObject;
+
+/**
+ * Extensible class that specifies the prize for a tourney.
+ */
+public abstract class Prize extends SimpleStreamableObject
+{
+ /**
+ * Returns a description of the prize.
+ */
+ public abstract String getDescription ();
+}
diff --git a/src/java/com/threerings/parlor/tourney/data/TourneyCodes.java b/src/java/com/threerings/parlor/tourney/data/TourneyCodes.java
new file mode 100644
index 00000000..d5fdbede
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/data/TourneyCodes.java
@@ -0,0 +1,54 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.data;
+
+import com.threerings.presents.data.InvocationCodes;
+
+/**
+ * Constants and codes relating to the tourney services.
+ */
+public interface TourneyCodes extends InvocationCodes
+{
+ /** Too late to join a tourney. */
+ public static final String TOO_LATE = "m.too_late";
+
+ /** User already in a tourney. */
+ public static final String ALREADY_IN_TOURNEY = "m.already_in_tourney";
+
+ /** User failed to meet the entry fee requirements. */
+ public static final String FAILED_ENTRY_FEE = "m.failed_entry_fee";
+
+ /** It's too late to leave the tourney. */
+ public static final String TOO_LATE_LEAVE = "m.too_late_leave";
+
+ /** User is not in the tourney. */
+ public static final String NOT_IN_TOURNEY = "m.not_in_tourney";
+
+ /** The tourney is already in progress. */
+ public static final String ALREADY_IN_PROGRESS = "m.already_in_progress";
+
+ /** This tourney has participating players. */
+ public static final String HAS_PLAYERS = "m.has_players";
+
+ /** The tournament was canceled. */
+ public static final String CANCELLED = "m.cancelled";
+}
diff --git a/src/java/com/threerings/parlor/tourney/data/TourneyConfig.java b/src/java/com/threerings/parlor/tourney/data/TourneyConfig.java
new file mode 100644
index 00000000..cf73b038
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/data/TourneyConfig.java
@@ -0,0 +1,53 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.data;
+
+import com.threerings.io.SimpleStreamableObject;
+import com.threerings.presents.dobj.DSet;
+import com.threerings.util.Name;
+
+/**
+ * Stores tournament configuration data.
+ */
+public class TourneyConfig extends SimpleStreamableObject
+{
+ /** Our unique tourney id. */
+ public int tourneyId;
+
+ /** The prize for this tourney. */
+ public Prize prize;
+
+ /** The fee to join the tourney. */
+ public EntryFee entryFee;
+
+ /** The tourney creator. */
+ public Name creator;
+
+ /** The minimum number of players needed for the tourney to start. */
+ public int minPlayers;
+
+ /** The number of minutes to wait for entrants before starting. */
+ public int startsIn;
+
+ /** The tournament logic runtime persistent data. */
+ public TourneyLogicData logic;
+}
diff --git a/src/java/com/threerings/parlor/tourney/data/TourneyLogicData.java b/src/java/com/threerings/parlor/tourney/data/TourneyLogicData.java
new file mode 100644
index 00000000..d158cc02
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/data/TourneyLogicData.java
@@ -0,0 +1,31 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.data;
+
+import com.threerings.io.SimpleStreamableObject;
+
+/**
+ * Contains TourneyLogic runtime data that should be persisted.
+ */
+public class TourneyLogicData extends SimpleStreamableObject
+{
+}
diff --git a/src/java/com/threerings/parlor/tourney/data/TourneyMarshaller.java b/src/java/com/threerings/parlor/tourney/data/TourneyMarshaller.java
new file mode 100644
index 00000000..c107eaee
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/data/TourneyMarshaller.java
@@ -0,0 +1,78 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.data;
+
+import com.threerings.parlor.tourney.client.TourneyService;
+import com.threerings.presents.client.Client;
+import com.threerings.presents.client.InvocationService;
+import com.threerings.presents.data.InvocationMarshaller;
+import com.threerings.presents.dobj.InvocationResponseEvent;
+
+/**
+ * Provides the implementation of the {@link TourneyService} interface
+ * that marshalls the arguments and delivers the request to the provider
+ * on the server. Also provides an implementation of the response listener
+ * interfaces that marshall the response arguments and deliver them back
+ * to the requesting client.
+ */
+public class TourneyMarshaller extends InvocationMarshaller
+ implements TourneyService
+{
+ /** The method id used to dispatch {@link #cancel} requests. */
+ public static final int CANCEL = 1;
+
+ // from interface TourneyService
+ public void cancel (Client arg1, InvocationService.ConfirmListener arg2)
+ {
+ InvocationMarshaller.ConfirmMarshaller listener2 = new InvocationMarshaller.ConfirmMarshaller();
+ listener2.listener = arg2;
+ sendRequest(arg1, CANCEL, new Object[] {
+ listener2
+ });
+ }
+
+ /** The method id used to dispatch {@link #join} requests. */
+ public static final int JOIN = 2;
+
+ // from interface TourneyService
+ public void join (Client arg1, InvocationService.ConfirmListener arg2)
+ {
+ InvocationMarshaller.ConfirmMarshaller listener2 = new InvocationMarshaller.ConfirmMarshaller();
+ listener2.listener = arg2;
+ sendRequest(arg1, JOIN, new Object[] {
+ listener2
+ });
+ }
+
+ /** The method id used to dispatch {@link #leave} requests. */
+ public static final int LEAVE = 3;
+
+ // from interface TourneyService
+ public void leave (Client arg1, InvocationService.ConfirmListener arg2)
+ {
+ InvocationMarshaller.ConfirmMarshaller listener2 = new InvocationMarshaller.ConfirmMarshaller();
+ listener2.listener = arg2;
+ sendRequest(arg1, LEAVE, new Object[] {
+ listener2
+ });
+ }
+}
diff --git a/src/java/com/threerings/parlor/tourney/data/TourneyObject.java b/src/java/com/threerings/parlor/tourney/data/TourneyObject.java
new file mode 100644
index 00000000..28668ecb
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/data/TourneyObject.java
@@ -0,0 +1,192 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.data;
+
+import com.threerings.presents.dobj.DObject;
+import com.threerings.presents.dobj.DSet;
+
+/**
+ * Provides information on a specific tourney.
+ */
+public class TourneyObject extends DObject
+{
+ // AUTO-GENERATED: FIELDS START
+ /** The field name of the state field. */
+ public static final String STATE = "state";
+
+ /** The field name of the config field. */
+ public static final String CONFIG = "config";
+
+ /** The field name of the startsIn field. */
+ public static final String STARTS_IN = "startsIn";
+
+ /** The field name of the tourneyService field. */
+ public static final String TOURNEY_SERVICE = "tourneyService";
+
+ /** The field name of the participants field. */
+ public static final String PARTICIPANTS = "participants";
+ // AUTO-GENERATED: FIELDS END
+
+ /** Tourney is pending and accepting participants. */
+ public static final int PENDING = 0;
+
+ /** Tourney is currently running. */
+ public static final int RUNNING = 1;
+
+ /** Tourney has been cancelled. */
+ public static final int CANCELLED = 2;
+
+ /** Tourney is paused. */
+ public static final int PAUSED = 3;
+
+ /** Tourney has completed. */
+ public static final int FINISHED = 4;
+
+ /** The current state of the tourney. */
+ public int state = PENDING;
+
+ /** The tourney configuration. */
+ public TourneyConfig config;
+
+ /** The real-time number of minutes before it starts. */
+ public int startsIn;
+
+ /** Provides the way in which tourney participants can communicate with the server. */
+ public TourneyMarshaller tourneyService;
+
+ /** A DSet that accumulates Participant records for the players involved in this tourney. */
+ public DSet participants = new DSet();
+
+ // AUTO-GENERATED: METHODS START
+ /**
+ * Requests that the state field be set to the
+ * specified value. The local value will be updated immediately and an
+ * event will be propagated through the system to notify all listeners
+ * that the attribute did change. Proxied copies of this object (on
+ * clients) will apply the value change when they received the
+ * attribute changed notification.
+ */
+ public void setState (int value)
+ {
+ int ovalue = this.state;
+ requestAttributeChange(
+ STATE, Integer.valueOf(value), Integer.valueOf(ovalue));
+ this.state = value;
+ }
+
+ /**
+ * Requests that the config field be set to the
+ * specified value. The local value will be updated immediately and an
+ * event will be propagated through the system to notify all listeners
+ * that the attribute did change. Proxied copies of this object (on
+ * clients) will apply the value change when they received the
+ * attribute changed notification.
+ */
+ public void setConfig (TourneyConfig value)
+ {
+ TourneyConfig ovalue = this.config;
+ requestAttributeChange(
+ CONFIG, value, ovalue);
+ this.config = value;
+ }
+
+ /**
+ * Requests that the startsIn field be set to the
+ * specified value. The local value will be updated immediately and an
+ * event will be propagated through the system to notify all listeners
+ * that the attribute did change. Proxied copies of this object (on
+ * clients) will apply the value change when they received the
+ * attribute changed notification.
+ */
+ public void setStartsIn (int value)
+ {
+ int ovalue = this.startsIn;
+ requestAttributeChange(
+ STARTS_IN, Integer.valueOf(value), Integer.valueOf(ovalue));
+ this.startsIn = value;
+ }
+
+ /**
+ * Requests that the tourneyService field be set to the
+ * specified value. The local value will be updated immediately and an
+ * event will be propagated through the system to notify all listeners
+ * that the attribute did change. Proxied copies of this object (on
+ * clients) will apply the value change when they received the
+ * attribute changed notification.
+ */
+ public void setTourneyService (TourneyMarshaller value)
+ {
+ TourneyMarshaller ovalue = this.tourneyService;
+ requestAttributeChange(
+ TOURNEY_SERVICE, value, ovalue);
+ this.tourneyService = value;
+ }
+
+ /**
+ * Requests that the specified entry be added to the
+ * participants set. The set will not change until the event is
+ * actually propagated through the system.
+ */
+ public void addToParticipants (Participant elem)
+ {
+ requestEntryAdd(PARTICIPANTS, participants, elem);
+ }
+
+ /**
+ * Requests that the entry matching the supplied key be removed from
+ * the participants set. The set will not change until the
+ * event is actually propagated through the system.
+ */
+ public void removeFromParticipants (Comparable key)
+ {
+ requestEntryRemove(PARTICIPANTS, participants, key);
+ }
+
+ /**
+ * Requests that the specified entry be updated in the
+ * participants set. The set will not change until the event is
+ * actually propagated through the system.
+ */
+ public void updateParticipants (Participant elem)
+ {
+ requestEntryUpdate(PARTICIPANTS, participants, elem);
+ }
+
+ /**
+ * Requests that the participants field be set to the
+ * specified value. Generally one only adds, updates and removes
+ * entries of a distributed set, but certain situations call for a
+ * complete replacement of the set value. The local value will be
+ * updated immediately and an event will be propagated through the
+ * system to notify all listeners that the attribute did
+ * change. Proxied copies of this object (on clients) will apply the
+ * value change when they received the attribute changed notification.
+ */
+ public void setParticipants (DSet value)
+ {
+ requestAttributeChange(PARTICIPANTS, value, this.participants);
+ @SuppressWarnings("unchecked") DSet clone =
+ (value == null) ? null : value.typedClone();
+ this.participants = clone;
+ }
+ // AUTO-GENERATED: METHODS END
+}
diff --git a/src/java/com/threerings/parlor/tourney/data/TourniesMarshaller.java b/src/java/com/threerings/parlor/tourney/data/TourniesMarshaller.java
new file mode 100644
index 00000000..3349c279
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/data/TourniesMarshaller.java
@@ -0,0 +1,53 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.data;
+
+import com.threerings.parlor.tourney.client.TourniesService;
+import com.threerings.parlor.tourney.data.TourneyConfig;
+import com.threerings.presents.client.Client;
+import com.threerings.presents.client.InvocationService;
+import com.threerings.presents.data.InvocationMarshaller;
+import com.threerings.presents.dobj.InvocationResponseEvent;
+
+/**
+ * Provides the implementation of the {@link TourniesService} interface
+ * that marshalls the arguments and delivers the request to the provider
+ * on the server. Also provides an implementation of the response listener
+ * interfaces that marshall the response arguments and deliver them back
+ * to the requesting client.
+ */
+public class TourniesMarshaller extends InvocationMarshaller
+ implements TourniesService
+{
+ /** The method id used to dispatch {@link #createTourney} requests. */
+ public static final int CREATE_TOURNEY = 1;
+
+ // from interface TourniesService
+ public void createTourney (Client arg1, TourneyConfig arg2, InvocationService.ResultListener arg3)
+ {
+ InvocationMarshaller.ResultMarshaller listener3 = new InvocationMarshaller.ResultMarshaller();
+ listener3.listener = arg3;
+ sendRequest(arg1, CREATE_TOURNEY, new Object[] {
+ arg2, listener3
+ });
+ }
+}
diff --git a/src/java/com/threerings/parlor/tourney/server/TourneyDispatcher.java b/src/java/com/threerings/parlor/tourney/server/TourneyDispatcher.java
new file mode 100644
index 00000000..91a06941
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/server/TourneyDispatcher.java
@@ -0,0 +1,85 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.server;
+
+import com.threerings.parlor.tourney.client.TourneyService;
+import com.threerings.parlor.tourney.data.TourneyMarshaller;
+import com.threerings.presents.client.Client;
+import com.threerings.presents.client.InvocationService;
+import com.threerings.presents.data.ClientObject;
+import com.threerings.presents.data.InvocationMarshaller;
+import com.threerings.presents.server.InvocationDispatcher;
+import com.threerings.presents.server.InvocationException;
+
+/**
+ * Dispatches requests to the {@link TourneyProvider}.
+ */
+public class TourneyDispatcher extends InvocationDispatcher
+{
+ /**
+ * Creates a dispatcher that may be registered to dispatch invocation
+ * service requests for the specified provider.
+ */
+ public TourneyDispatcher (TourneyProvider provider)
+ {
+ this.provider = provider;
+ }
+
+ // from InvocationDispatcher
+ public InvocationMarshaller createMarshaller ()
+ {
+ return new TourneyMarshaller();
+ }
+
+ @SuppressWarnings("unchecked") // from InvocationDispatcher
+ public void dispatchRequest (
+ ClientObject source, int methodId, Object[] args)
+ throws InvocationException
+ {
+ switch (methodId) {
+ case TourneyMarshaller.CANCEL:
+ ((TourneyProvider)provider).cancel(
+ source,
+ (InvocationService.ConfirmListener)args[0]
+ );
+ return;
+
+ case TourneyMarshaller.JOIN:
+ ((TourneyProvider)provider).join(
+ source,
+ (InvocationService.ConfirmListener)args[0]
+ );
+ return;
+
+ case TourneyMarshaller.LEAVE:
+ ((TourneyProvider)provider).leave(
+ source,
+ (InvocationService.ConfirmListener)args[0]
+ );
+ return;
+
+ default:
+ super.dispatchRequest(source, methodId, args);
+ return;
+ }
+ }
+}
diff --git a/src/java/com/threerings/parlor/tourney/server/TourneyManager.java b/src/java/com/threerings/parlor/tourney/server/TourneyManager.java
new file mode 100644
index 00000000..b1ee5798
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/server/TourneyManager.java
@@ -0,0 +1,308 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.server;
+
+import com.samskivert.util.Interval;
+import com.samskivert.util.ResultListener;
+
+import com.threerings.util.Name;
+
+import com.threerings.crowd.data.BodyObject;
+
+import com.threerings.parlor.tourney.data.Participant;
+import com.threerings.parlor.tourney.data.TourneyConfig;
+import com.threerings.parlor.tourney.data.TourneyCodes;
+import com.threerings.parlor.tourney.data.TourneyMarshaller;
+import com.threerings.parlor.tourney.data.TourneyObject;
+
+import com.threerings.presents.client.InvocationService;
+import com.threerings.presents.server.InvocationException;
+import com.threerings.presents.server.InvocationManager;
+import com.threerings.presents.server.PresentsDObjectMgr;
+import com.threerings.presents.data.ClientObject;
+
+/**
+ * Controls a running tourney.
+ */
+public abstract class TourneyManager
+ implements TourneyProvider, TourneyCodes
+{
+ public TourneyManager (TourneyConfig config, TourniesManager tmgr, Comparable key,
+ InvocationService.ResultListener listener)
+ {
+ _config = config;
+ _tmgr = tmgr;
+ _key = key;
+
+ // creare and configure our Tourney object
+ _trobj = getOMgr().registerObject(new TourneyObject());
+ _trobj.setTourneyService((TourneyMarshaller)getInvMgr().registerDispatcher(
+ new TourneyDispatcher(this)));
+
+ _trobj.config = config;
+
+ // if we've got logic data already then we must be resuming a persisted tournament
+ if (config.logic != null) {
+ _trobj.state = TourneyObject.PAUSED;
+ } else {
+ _trobj.startsIn = config.startsIn;
+ // keep track of when we start in millis
+ _startTime = System.currentTimeMillis() + (MINUTE * _config.startsIn);
+ }
+
+ if (listener != null) {
+ listener.requestProcessed(Integer.valueOf(_trobj.getOid()));
+ }
+ }
+
+ // documentation inherited from TourneyProvider
+ public void cancel (ClientObject caller, InvocationService.ConfirmListener listener)
+ throws InvocationException
+ {
+ // don't allow cancelation of a running tourney
+ if (_trobj.state != TourneyObject.PENDING) {
+ throw new InvocationException(ALREADY_IN_PROGRESS);
+
+ // or a tourney that already has participants
+ } else if (_trobj.participants.size() != 0) {
+ throw new InvocationException(HAS_PLAYERS);
+
+ } else {
+ cancelTourney(CANCELLED);
+ }
+ }
+
+ // documentation inherited from TourneyProvider
+ public void join (ClientObject caller, final InvocationService.ConfirmListener listener)
+ throws InvocationException
+ {
+ BodyObject body = (BodyObject)caller;
+
+ // make sure the tourney hasn't already started
+ if (_trobj.state != TourneyObject.PENDING) {
+ throw new InvocationException(TOO_LATE);
+ }
+
+ // make sure they haven't already signed up
+ final Participant part = makeParticipant(body);
+ if (_trobj.participants.contains(part)) {
+ throw new InvocationException(ALREADY_IN_TOURNEY);
+ }
+
+ // allow the implementing class to do further join checks
+ joinTourney(body);
+
+ // check the entrance fee
+ if (_trobj.config.entryFee != null) {
+ if (!_trobj.config.entryFee.hasFee(body)) {
+ listener.requestFailed("FAILED_ENTRY_FEE");
+ return;
+ }
+
+ // make the assumption that they're going to get in
+ _trobj.addToParticipants(part);
+
+ ResultListener rl = new ResultListener() {
+ public void requestCompleted (Object result) {
+ listener.requestProcessed();
+ }
+ public void requestFailed (Exception cause) {
+ // remove them from the tourney
+ _trobj.removeFromParticipants(part.getKey());
+ listener.requestFailed("FAILED_ENTRY_FEE");
+ }
+ };
+
+ _trobj.config.entryFee.reserveFee(body, rl);
+
+ } else {
+ _trobj.addToParticipants(part);
+ listener.requestProcessed();
+ }
+ }
+
+ // documentation inherited from TourneyProvider
+ public void leave (ClientObject caller, InvocationService.ConfirmListener listener)
+ throws InvocationException
+ {
+ BodyObject body = (BodyObject)caller;
+
+ // can't leave unless the tourney is just pending
+ if (_trobj.state != TourneyObject.PENDING) {
+ throw new InvocationException(TOO_LATE_LEAVE);
+ }
+
+ Comparable key = body.username;
+ if (!_trobj.participants.containsKey(key)) {
+ throw new InvocationException(NOT_IN_TOURNEY);
+ }
+
+ // remove them IMMEDIATELY from the participation list
+ _trobj.removeFromParticipants(key);
+
+ // return the entry fee
+ if (_trobj.config.entryFee != null) {
+ _trobj.config.entryFee.returnFee(body);
+ }
+
+ listener.requestProcessed();
+ }
+
+ /**
+ * Cancel the tourney, return entry fees to all participants.
+ */
+ public void cancelTourney (String cause)
+ {
+ if (isFinished()) {
+ // show's over, nothing to see here
+ return;
+ }
+
+ _trobj.setState(TourneyObject.CANCELLED);
+
+ notifyAllParticipants(cause);
+
+ // return the fees
+ if (_trobj.config.entryFee != null) {
+ for (Participant part : _trobj.participants) {
+ BodyObject body = lookupBody(part.username);
+ if (body != null) {
+ _trobj.config.entryFee.returnFee(body);
+ }
+ }
+ }
+
+ releaseTourney();
+ }
+
+ /**
+ * Returns true if the tourney is finished.
+ */
+ public boolean isFinished ()
+ {
+ return _trobj == null ? false :
+ _trobj.state == TourneyObject.FINISHED || _trobj.state == TourneyObject.CANCELLED;
+ }
+
+ /**
+ * Returns true if the tourney is pending.
+ */
+ public boolean isPending ()
+ {
+ return _trobj == null ? false : _trobj.state == TourneyObject.PENDING;
+ }
+
+ /**
+ * Returns true if the tourney is running.
+ */
+ public boolean isRunning ()
+ {
+ return _trobj == null ? false : _trobj.state == TourneyObject.RUNNING;
+ }
+
+ /**
+ * Returns true if the tourney is paused.
+ */
+ public boolean isPaused ()
+ {
+ return _trobj == null ? false : _trobj.state == TourneyObject.PAUSED;
+ }
+
+ /**
+ * Returns true if it is time or past time the tourney starts.
+ */
+ public boolean shouldStart (long now)
+ {
+ return _trobj == null ? false : _startTime <= now;
+ }
+
+ /** Creates a {@link Participant} record for the specified user. */
+ protected Participant makeParticipant (BodyObject body)
+ {
+ Participant part = new Participant();
+ part.username = body.username;
+ return part;
+ }
+
+ public abstract void notifyAllParticipants (String msg);
+
+ /**
+ * Releases the tourney from the tourney manager, and removes the tourney from the list of
+ * tournies.
+ */
+ protected void releaseTourney ()
+ {
+ _tmgr.releaseTourney(_key);
+
+ // release the tourney provider
+ if (_trobj.tourneyService != null) {
+ getInvMgr().clearDispatcher(_trobj.tourneyService);
+ _trobj.tourneyService = null;
+ }
+
+ // destroy the object in a couple of minutes
+ new Interval(getOMgr()) {
+ public void expired () {
+ getOMgr().destroyObject(_trobj.getOid());
+ }
+ }.schedule(MINUTE * 2);
+ }
+
+ /**
+ * Returns a reference to our distributed object manager.
+ */
+ protected abstract PresentsDObjectMgr getOMgr ();
+
+ /**
+ * Returns a reference to our invocation manager.
+ */
+ protected abstract InvocationManager getInvMgr ();
+
+ /**
+ * Looks up the BodyObject for a username.
+ */
+ protected abstract BodyObject lookupBody (Name username);
+
+ /**
+ * Will throw an InvocationException if the user cannot join the tourney.
+ */
+ protected abstract void joinTourney (BodyObject body)
+ throws InvocationException;
+
+ /** One minute in milliseconds. */
+ protected static long MINUTE = 60 * 1000L;
+
+ /** Our touney configuration. */
+ protected TourneyConfig _config;
+
+ /** Our distributed tourney object. */
+ protected TourneyObject _trobj;
+
+ /** Reference to the tournies manager. */
+ protected TourniesManager _tmgr;
+
+ /** The time, in milliseconds, when the tourney starts. */
+ protected long _startTime;
+
+ /** The key this tourney is recorded under. */
+ protected Comparable _key;
+}
diff --git a/src/java/com/threerings/parlor/tourney/server/TourneyProvider.java b/src/java/com/threerings/parlor/tourney/server/TourneyProvider.java
new file mode 100644
index 00000000..c71ce290
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/server/TourneyProvider.java
@@ -0,0 +1,53 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.server;
+
+import com.threerings.parlor.tourney.client.TourneyService;
+import com.threerings.presents.client.Client;
+import com.threerings.presents.client.InvocationService;
+import com.threerings.presents.data.ClientObject;
+import com.threerings.presents.server.InvocationException;
+import com.threerings.presents.server.InvocationProvider;
+
+/**
+ * Defines the server-side of the {@link TourneyService}.
+ */
+public interface TourneyProvider extends InvocationProvider
+{
+ /**
+ * Handles a {@link TourneyService#cancel} request.
+ */
+ public void cancel (ClientObject caller, InvocationService.ConfirmListener arg1)
+ throws InvocationException;
+
+ /**
+ * Handles a {@link TourneyService#join} request.
+ */
+ public void join (ClientObject caller, InvocationService.ConfirmListener arg1)
+ throws InvocationException;
+
+ /**
+ * Handles a {@link TourneyService#leave} request.
+ */
+ public void leave (ClientObject caller, InvocationService.ConfirmListener arg1)
+ throws InvocationException;
+}
diff --git a/src/java/com/threerings/parlor/tourney/server/TourniesDispatcher.java b/src/java/com/threerings/parlor/tourney/server/TourniesDispatcher.java
new file mode 100644
index 00000000..88a6acfb
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/server/TourniesDispatcher.java
@@ -0,0 +1,72 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.server;
+
+import com.threerings.parlor.tourney.client.TourniesService;
+import com.threerings.parlor.tourney.data.TourneyConfig;
+import com.threerings.parlor.tourney.data.TourniesMarshaller;
+import com.threerings.presents.client.Client;
+import com.threerings.presents.client.InvocationService;
+import com.threerings.presents.data.ClientObject;
+import com.threerings.presents.data.InvocationMarshaller;
+import com.threerings.presents.server.InvocationDispatcher;
+import com.threerings.presents.server.InvocationException;
+
+/**
+ * Dispatches requests to the {@link TourniesProvider}.
+ */
+public class TourniesDispatcher extends InvocationDispatcher
+{
+ /**
+ * Creates a dispatcher that may be registered to dispatch invocation
+ * service requests for the specified provider.
+ */
+ public TourniesDispatcher (TourniesProvider provider)
+ {
+ this.provider = provider;
+ }
+
+ // from InvocationDispatcher
+ public InvocationMarshaller createMarshaller ()
+ {
+ return new TourniesMarshaller();
+ }
+
+ @SuppressWarnings("unchecked") // from InvocationDispatcher
+ public void dispatchRequest (
+ ClientObject source, int methodId, Object[] args)
+ throws InvocationException
+ {
+ switch (methodId) {
+ case TourniesMarshaller.CREATE_TOURNEY:
+ ((TourniesProvider)provider).createTourney(
+ source,
+ (TourneyConfig)args[0], (InvocationService.ResultListener)args[1]
+ );
+ return;
+
+ default:
+ super.dispatchRequest(source, methodId, args);
+ return;
+ }
+ }
+}
diff --git a/src/java/com/threerings/parlor/tourney/server/TourniesManager.java b/src/java/com/threerings/parlor/tourney/server/TourniesManager.java
new file mode 100644
index 00000000..c261b482
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/server/TourniesManager.java
@@ -0,0 +1,154 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.server;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import com.samskivert.util.Interval;
+import com.samskivert.util.RunQueue;
+
+import com.samskivert.io.PersistenceException;
+import com.samskivert.jdbc.ConnectionProvider;
+
+import com.threerings.parlor.tourney.server.persist.TourneyRepository;
+import com.threerings.parlor.tourney.data.Prize;
+import com.threerings.parlor.tourney.data.TourneyConfig;
+
+import com.threerings.presents.client.InvocationService;
+import com.threerings.presents.server.InvocationException;
+import com.threerings.presents.server.PresentsServer;
+import com.threerings.presents.data.ClientObject;
+
+/**
+ * An extensible tournament manager.
+ */
+public abstract class TourniesManager
+ implements TourniesProvider, PresentsServer.Shutdowner
+{
+ public TourniesManager (ConnectionProvider conprov)
+ throws PersistenceException
+ {
+ _tournrep = new TourneyRepository(conprov, getDBIdent());
+
+ loadTourneyConfigs();
+ }
+
+ public void init ()
+ {
+ _interval = new Interval(getRunQueue()) {
+ public void expired () {
+ updateTournies();
+ }
+ };
+ _interval.schedule(getIntervalDelay(), true);
+ }
+
+ // documentation inherited from interface PresentsServer.Shutdowner
+ public void shutdown ()
+ {
+ _interval.cancel();
+ }
+
+ // documentation inherited from interface TourniesService
+ public void createTourney (ClientObject caller, TourneyConfig config,
+ final InvocationService.ResultListener listener)
+ throws InvocationException
+ {
+ makeTourney(config, listener);
+ }
+
+ /**
+ * Called to actually create a tourney once it has been validated and the prize has been
+ * reserved.
+ */
+ protected void makeTourney (TourneyConfig config, InvocationService.ResultListener listener)
+ {
+ // create a new tourney manager which will run things
+ Integer tourneyID = Integer.valueOf(_tourneyCount++);
+ _tourneys.put(tourneyID, makeTourneyManager(config, tourneyID, listener));
+ }
+
+ /**
+ * Called by the tourney manager to remove itself from the tournies.
+ */
+ protected void releaseTourney (Comparable key)
+ {
+ _tourneys.remove(key);
+ }
+
+ /**
+ * Load all the tournament configuration information stored in the repository.
+ */
+ protected void loadTourneyConfigs ()
+ throws PersistenceException
+ {
+ ArrayList tournies = _tournrep.loadTournies();
+ for (TourneyConfig config : tournies) {
+ makeTourney(config, null);
+ }
+
+ }
+
+ /**
+ * Called to update loaded tournies, possibly announcing tourney information or start a
+ * pending tourney.
+ */
+ protected void updateTournies ()
+ {
+ }
+
+ /**
+ * Instantiates a new tourney manager.
+ */
+ protected abstract TourneyManager makeTourneyManager(
+ TourneyConfig config, Comparable key, InvocationService.ResultListener listener);
+
+ /**
+ * Returns the database identifier for our repository.
+ */
+ protected abstract String getDBIdent ();
+
+ /**
+ * Returns the RunQueue to use for our tourney interval.
+ */
+ protected abstract RunQueue getRunQueue ();
+
+ /**
+ * Returns the tourney interval delay in milliseconds.
+ */
+ protected abstract long getIntervalDelay ();
+
+ /** Holds all the current tournies in the game. */
+ protected HashMap _tourneys =
+ new HashMap();
+
+ /** Reference to our tourney repository. */
+ protected TourneyRepository _tournrep;
+
+ /** The interval which updates loaded tournies. */
+ protected Interval _interval;
+
+ /** Count to provide a unique key to tournies as they're created. */
+ protected int _tourneyCount;
+}
diff --git a/src/java/com/threerings/parlor/tourney/server/TourniesProvider.java b/src/java/com/threerings/parlor/tourney/server/TourniesProvider.java
new file mode 100644
index 00000000..cd365658
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/server/TourniesProvider.java
@@ -0,0 +1,42 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.server;
+
+import com.threerings.parlor.tourney.client.TourniesService;
+import com.threerings.parlor.tourney.data.TourneyConfig;
+import com.threerings.presents.client.Client;
+import com.threerings.presents.client.InvocationService;
+import com.threerings.presents.data.ClientObject;
+import com.threerings.presents.server.InvocationException;
+import com.threerings.presents.server.InvocationProvider;
+
+/**
+ * Defines the server-side of the {@link TourniesService}.
+ */
+public interface TourniesProvider extends InvocationProvider
+{
+ /**
+ * Handles a {@link TourniesService#createTourney} request.
+ */
+ public void createTourney (ClientObject caller, TourneyConfig arg1, InvocationService.ResultListener arg2)
+ throws InvocationException;
+}
diff --git a/src/java/com/threerings/parlor/tourney/server/persist/TourneyRepository.java b/src/java/com/threerings/parlor/tourney/server/persist/TourneyRepository.java
new file mode 100644
index 00000000..163dd0b9
--- /dev/null
+++ b/src/java/com/threerings/parlor/tourney/server/persist/TourneyRepository.java
@@ -0,0 +1,166 @@
+//
+// $Id$
+//
+// Vilya library - tools for developing networked games
+// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/vilya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.parlor.tourney.server.persist;
+
+import java.util.ArrayList;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import com.samskivert.io.PersistenceException;
+
+import com.samskivert.jdbc.ConnectionProvider;
+import com.samskivert.jdbc.DatabaseLiaison;
+import com.samskivert.jdbc.JDBCUtil;
+import com.samskivert.jdbc.JORARepository;
+
+import com.samskivert.jdbc.jora.Table;
+
+import com.threerings.io.ObjectInputStream;
+import com.threerings.io.ObjectOutputStream;
+
+import com.threerings.parlor.tourney.data.TourneyConfig;
+
+import static com.threerings.parlor.Log.log;
+
+/**
+ * The persistent store for tourney related information.
+ */
+public class TourneyRepository extends JORARepository
+{
+ /** Contains tourney information loaded from the database. */
+ public static class TourneyRecord
+ {
+ /** The tourney's unique identifier. */
+ public int tourneyId;
+
+ /** The tourney configuration. */
+ public byte[] config;
+
+ public TourneyRecord ()
+ {
+ }
+
+ public TourneyRecord (int tourneyId)
+ {
+ this.tourneyId = tourneyId;
+ }
+
+ public TourneyRecord (TourneyConfig tourneyConfig)
+ {
+ this(tourneyConfig.tourneyId);
+ ByteArrayOutputStream bstream = new ByteArrayOutputStream();
+ ObjectOutputStream ostream = new ObjectOutputStream(bstream);
+
+ try {
+ ostream.writeObject(config);
+ config = bstream.toByteArray();
+
+ } catch (IOException e) {
+ log.warning("Error writing TourneyConfig to byte array [e=" + e + "].");
+ }
+
+ }
+
+ public TourneyConfig getTourneyConfig ()
+ {
+ ObjectInputStream ostream = new ObjectInputStream(new ByteArrayInputStream(config));
+ TourneyConfig tconfig = null;
+
+ try {
+ tconfig = (TourneyConfig)ostream.readObject();
+
+ } catch (Exception e) {
+ log.warning("Error reading TourneyConfig from byte array [e=" + e + "].");
+ }
+ return tconfig;
+ }
+ }
+
+ public TourneyRepository (ConnectionProvider conprov, String dbident)
+ {
+ super(conprov, dbident);
+ }
+
+ /**
+ * Inserts a new tourney into the repository, assigning a unique id to the tourney.
+ */
+ public void insertTourney (TourneyConfig tourney)
+ throws PersistenceException
+ {
+ tourney.tourneyId = insert(_ttable, new TourneyRecord(tourney));
+ }
+
+ /**
+ * Updates the tourney in the repository.
+ */
+ public void updateTourney (TourneyConfig tourney)
+ throws PersistenceException
+ {
+ store(_ttable, new TourneyRecord(tourney));
+ }
+
+ /**
+ * Deletes a tourney from the repository.
+ */
+ public void deleteTourney (int tourneyId)
+ throws PersistenceException
+ {
+ delete(_ttable, new TourneyRecord(tourneyId));
+ }
+
+ /**
+ * Loads all the tourney configs from the repository.
+ */
+ public ArrayList loadTournies ()
+ throws PersistenceException
+ {
+ ArrayList recordList = loadAll(_ttable, "");
+ ArrayList configList = new ArrayList(recordList.size());
+ for (TourneyRecord record : recordList) {
+ configList.add(record.getTourneyConfig());
+ }
+ return configList;
+ }
+
+ @Override // documentation inherited
+ protected void migrateSchema (Connection conn, DatabaseLiaison liaison)
+ throws SQLException, PersistenceException
+ {
+ JDBCUtil.createTableIfMissing(conn, "TOURNEYS", new String[] {
+ "TOURNEY_ID INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY",
+ "CONFIG BLOB"
+ }, "");
+ }
+
+ @Override // documentation inherited
+ protected void createTables ()
+ {
+ _ttable = new Table(TourneyRecord.class, "TOURNEYS", "TOURNEY_ID", true);
+ }
+
+ protected Table _ttable;
+}