Search in sources :

Example 36 with Connection

use of soc.server.genericServer.Connection in project JSettlers2 by jdmonin.

the class SOCServer method messageToGameExcept.

/**
 * Send a message to all the connections in a game, excluding one.
 *
 * @param gn  the name of the game
 * @param ex  the excluded connection, or null
 * @param mes the message
 * @param takeMon Should this method take and release
 *                game's monitor via {@link SOCGameList#takeMonitorForGame(String)} ?
 * @see #messageToGameExcept(String, Connection, String, boolean)
 * @see #messageToGameExcept(String, List, SOCMessage, boolean)
 * @see #messageToGameForVersionsExcept(SOCGame, int, int, Connection, SOCMessage, boolean)
 */
public void messageToGameExcept(String gn, Connection ex, SOCMessage mes, boolean takeMon) {
    if (takeMon)
        gameList.takeMonitorForGame(gn);
    try {
        Vector<Connection> v = gameList.getMembers(gn);
        if (v != null) {
            // D.ebugPrintln("M2GE - "+mes);
            final String mesCmd = mes.toCmd();
            Enumeration<Connection> menum = v.elements();
            while (menum.hasMoreElements()) {
                Connection con = menum.nextElement();
                if ((con == null) || (con == ex))
                    continue;
                // currentGameEventRecord.addMessageOut(new SOCMessageRecord(mes, "SERVER", con.getData()));
                con.put(mesCmd);
            }
        }
    } catch (Exception e) {
        D.ebugPrintStackTrace(e, "Exception in messageToGameExcept");
    }
    if (takeMon)
        gameList.releaseMonitorForGame(gn);
}
Also used : StringConnection(soc.server.genericServer.StringConnection) Connection(soc.server.genericServer.Connection) MissingResourceException(java.util.MissingResourceException) EOFException(java.io.EOFException) DBSettingMismatchException(soc.server.database.DBSettingMismatchException) SocketException(java.net.SocketException) SQLException(java.sql.SQLException) IOException(java.io.IOException)

Example 37 with Connection

use of soc.server.genericServer.Connection in project JSettlers2 by jdmonin.

the class SOCServer method messageToGame.

/**
 * Send a server text message to the given game.
 * Equivalent to: messageToGame(ga, new SOCGameServerText(ga, txt));
 *<P>
 * Do not pass SOCSomeMessage.toCmd() into this method; the message type number
 * will be GAMESERVERTEXT, not the desired SOMEMESSAGE.
 *<P>
 * Client versions older than v2.0.00 will be sent
 * {@link SOCGameTextMsg}(ga, {@link #SERVERNAME}, txt).
 *<P>
 * <b>Locks:</b> Takes, releases {@link SOCGameList#takeMonitorForGame(String)}.
 *
 * @param ga  the name of the game
 * @param txt the message text to send. If
 *            text begins with ">>>", the client should consider this
 *            an urgent message, and draw the user's attention in some way.
 *            (See {@link #messageToGameUrgent(String, String)})
 * @see #messageToGameKeyed(SOCGame, boolean, String)
 * @see #messageToGameKeyed(SOCGame, boolean, String, Object...)
 * @see #messageToGame(String, SOCMessage)
 * @see #messageToGameWithMon(String, SOCMessage)
 * @see #messageToGameExcept(String, Connection, String, boolean)
 * @since 1.1.08
 */
public void messageToGame(final String ga, final String txt) {
    final String gameServTxtMsg = SOCGameServerText.toCmd(ga, txt);
    gameList.takeMonitorForGame(ga);
    try {
        Vector<Connection> v = gameList.getMembers(ga);
        if (v != null) {
            Enumeration<Connection> menum = v.elements();
            while (menum.hasMoreElements()) {
                Connection c = menum.nextElement();
                if (c != null) {
                    if (c.getVersion() >= SOCGameServerText.VERSION_FOR_GAMESERVERTEXT)
                        c.put(gameServTxtMsg);
                    else
                        c.put(SOCGameTextMsg.toCmd(ga, SERVERNAME, txt));
                }
            }
        }
    } catch (Throwable e) {
        D.ebugPrintStackTrace(e, "Exception in messageToGame");
    }
    gameList.releaseMonitorForGame(ga);
}
Also used : StringConnection(soc.server.genericServer.StringConnection) Connection(soc.server.genericServer.Connection)

Example 38 with Connection

use of soc.server.genericServer.Connection in project JSettlers2 by jdmonin.

the class SOCServer method impl_messageToGameKeyedSpecial.

/**
 * Implement {@link #messageToGameKeyed(SOCGame, boolean, String, Object...)},
 * {@code messageToGameKeyedSpecial}, and {@code messageToGameKeyedSpecialExcept}.
 *
 * @param ga  the game object
 * @param takeMon Should this method take and release
 *                game's monitor via {@link SOCGameList#takeMonitorForGame(String)} ?
 *                True unless caller already holds that monitor.
 * @param members  Game members to send to, from {@link SOCGameListAtServer#getMembers(String)}.
 *            Any member in this list with null locale (such as robots) will be skipped and not sent the message.
 *            If we're excluding several members of the game, make a new list from getMembers, remove them from
 *            that list, then pass it to this method.
 *            Returns immediately if {@code null}.
 * @param ex  the excluded connection, or {@code null}
 * @param fmtSpecial  Should this method call {@link SOCStringManager#getSpecial(SOCGame, String, Object...)}
 *            instead of the usual {@link SOCStringManager#get(String, Object...)} ?
 *            True if called from {@code messageToGameKeyedSpecial*}, false from other
 *            {@code messageToGameKeyed} methods.
 * @param key the message localization key, from {@link SOCStringManager#get(String)}, to look up and send text of.
 *            If its localized text begins with ">>>", the client should consider this
 *            an urgent message, and draw the user's attention in some way.
 *            (See {@link #messageToGameUrgent(String, String)})
 * @param params  Objects to use with <tt>{0}</tt>, <tt>{1}</tt>, etc in the localized string
 *             by calling {@link MessageFormat#format(String, Object...)}.
 *             <P>
 *             If {@code fmtSpecial}, these objects can include {@link SOCResourceSet} or pairs of
 *             Integers for a resource count and type; see {@link SOCStringManager#getSpecial(SOCGame, String, Object...)}.
 * @throws MissingResourceException if no string can be found for {@code key}; this is a RuntimeException
 * @throws IllegalArgumentException if the localized pattern string has a parse error (closing '}' brace without opening '{' brace, etc)
 * @since 2.0.00
 */
private final void impl_messageToGameKeyedSpecial(SOCGame ga, final boolean takeMon, final List<Connection> members, final Connection ex, final boolean fmtSpecial, final String key, final Object... params) throws MissingResourceException, IllegalArgumentException {
    if (members == null)
        return;
    // Very similar code to messageToGameKeyedType:
    // If you change code here, change it there too.
    // Indentation within try/catch matches messageToGameKeyedType's.
    final boolean hasMultiLocales = ga.hasMultiLocales;
    final String gaName = ga.getName();
    if (takeMon)
        gameList.takeMonitorForGame(gaName);
    try {
        Iterator<Connection> miter = members.iterator();
        // as rendered for previous client during loop
        String gameTextMsg = null, gameTxtLocale = null;
        while (miter.hasNext()) {
            Connection c = miter.next();
            if ((c == null) || (c == ex))
                continue;
            final String cliLocale = c.getI18NLocale();
            if (cliLocale == null)
                // skip bots
                continue;
            if ((gameTextMsg == null) || (hasMultiLocales && !cliLocale.equals(gameTxtLocale))) {
                if (fmtSpecial)
                    gameTextMsg = SOCGameServerText.toCmd(gaName, c.getLocalizedSpecial(ga, key, params));
                else
                    gameTextMsg = SOCGameServerText.toCmd(gaName, (params != null) ? c.getLocalized(key, params) : c.getLocalized(key));
                gameTxtLocale = cliLocale;
            }
            if ((c.getVersion() >= SOCGameServerText.VERSION_FOR_GAMESERVERTEXT) && (gameTextMsg != null))
                c.put(gameTextMsg);
            else // old client (this is uncommon) needs a different message type
            if (fmtSpecial)
                c.put(SOCGameTextMsg.toCmd(gaName, SERVERNAME, c.getLocalizedSpecial(ga, key, params)));
            else
                c.put(SOCGameTextMsg.toCmd(gaName, SERVERNAME, (params != null) ? c.getLocalized(key, params) : c.getLocalized(key)));
        }
    } catch (Throwable e) {
        D.ebugPrintStackTrace(e, (fmtSpecial) ? "Exception in messageToGameKeyedSpecial" : "Exception in messageToGameKeyed");
    }
    if (takeMon)
        gameList.releaseMonitorForGame(gaName);
}
Also used : StringConnection(soc.server.genericServer.StringConnection) Connection(soc.server.genericServer.Connection)

Example 39 with Connection

use of soc.server.genericServer.Connection in project JSettlers2 by jdmonin.

the class SOCServer method readyGameAskRobotsJoin.

/**
 * Fill all the unlocked empty seats with robots, by asking them to join.
 * Builds a set of the {@link Connection}s of robots asked to join,
 * and adds it to the {@code robotJoinRequests} table.
 * Game state should be {@code READY}.
 *<P>
 * At most {@link SOCGame#getAvailableSeatCount()} robots will
 * be asked. If third-party bots are connected to the server,
 * optional property {@link #PROP_JSETTLERS_BOTS_PERCENT3P} can
 * set a goal for the minimum percentage of third-party bots in
 * the game; see its javadoc.
 *<P>
 * Called by {@link SOCServerMessageHandler#handleSTARTGAME(Connection, SOCStartGame) handleSTARTGAME},
 * {@link #resetBoardAndNotify(String, int) resetBoardAndNotify}.
 *<P>
 * Once the robots have all responded (from their own threads/clients)
 * and joined up, the game can begin.
 *<P>
 * Before v1.1.00, this method was part of {@code handleSTARTGAME}.
 *
 * @param ga  Game to ask robots to join
 * @param robotSeats If robotSeats is null, robots are randomly selected.
 *                   If non-null, a MAXPLAYERS-sized array of Connections.
 *                   Any vacant non-locked seat, with index i,
 *                   is filled with the robot whose connection is robotSeats[i].
 *                   Other indexes should be null, and won't be used.
 * @param maxBots Maximum number of bots to add, or 0 to fill all empty seats
 *
 * @throws IllegalStateException if {@link SOCGame#getGameState() ga.gamestate} is not READY,
 *         or if {@link SOCGame#getClientVersionMinRequired() ga.version} is
 *         somehow newer than server's version (which is assumed to be robots' version).
 * @throws IllegalArgumentException if robotSeats is not null but wrong length,
 *           or if a robotSeat element is null but that seat wants a robot (vacant non-locked).
 * @since 1.1.00
 */
void readyGameAskRobotsJoin(SOCGame ga, Connection[] robotSeats, final int maxBots) throws IllegalStateException, IllegalArgumentException {
    if (ga.getGameState() != SOCGame.READY)
        throw new IllegalStateException("SOCGame state not READY: " + ga.getGameState());
    if (ga.getClientVersionMinRequired() > Version.versionNumber())
        throw new IllegalStateException("SOCGame version somehow newer than server and robots, it's " + ga.getClientVersionMinRequired());
    // These bots will be asked to join.
    // Key = bot Connection, value = seat number as {@link Integer} like in SOCServer.robotJoinRequests
    Hashtable<Connection, Object> robotsRequested = null;
    int[] robotIndexes = null;
    if (robotSeats == null) {
        // shuffle the indexes to distribute load
        robotIndexes = robotShuffleForJoin();
    } else {
        // robotSeats not null: check length
        if (robotSeats.length != ga.maxPlayers)
            throw new IllegalArgumentException("robotSeats Length must be MAXPLAYERS");
    }
    final String gname = ga.getName();
    final Map<String, SOCGameOption> gopts = ga.getGameOptions();
    int seatsOpen = ga.getAvailableSeatCount();
    if ((maxBots > 0) && (maxBots < seatsOpen))
        seatsOpen = maxBots;
    int idx = 0;
    Connection[] robotSeatsConns = new Connection[ga.maxPlayers];
    for (int i = 0; (i < ga.maxPlayers) && (seatsOpen > 0); i++) {
        if (ga.isSeatVacant(i) && (ga.getSeatLock(i) == SOCGame.SeatLockState.UNLOCKED)) {
            /**
             * fetch a robot player; game will start when all bots have arrived.
             * Similar to SOCGameHandler.findRobotAskJoinGame (called from SGH.leaveGame),
             * where a player has left and must be replaced by a bot.
             */
            if (idx < robots.size()) {
                // "Fetching a robot player..."
                messageToGameKeyed(ga, true, "member.bot.join.fetching");
                Connection robotConn;
                if (robotSeats != null) {
                    robotConn = robotSeats[i];
                    if (robotConn == null)
                        throw new IllegalArgumentException("robotSeats[" + i + "] was needed but null");
                } else {
                    robotConn = robots.get(robotIndexes[idx]);
                }
                idx++;
                --seatsOpen;
                robotSeatsConns[i] = robotConn;
                /**
                 * record the request
                 */
                if (robotsRequested == null)
                    robotsRequested = new Hashtable<Connection, Object>();
                robotsRequested.put(robotConn, Integer.valueOf(i));
            }
        }
    }
    if (robotsRequested != null) {
        // request third-party bots, if available and wanted
        final int reqPct3p = getConfigIntProperty(PROP_JSETTLERS_BOTS_PERCENT3P, 0);
        if (reqPct3p > 0)
            readyGameAskRobotsMix3p(reqPct3p, robotsRequested, robotSeatsConns);
        // we know robotRequests isn't empty,
        // so add to the request table
        robotJoinRequests.put(gname, robotsRequested);
        // now, make the requests
        for (int i = 0; i < ga.maxPlayers; ++i) {
            if (robotSeatsConns[i] != null) {
                D.ebugPrintln("@@@ JOIN GAME REQUEST for " + robotSeatsConns[i].getData());
                robotSeatsConns[i].put(SOCBotJoinGameRequest.toCmd(gname, i, gopts));
            }
        }
    }
}
Also used : Hashtable(java.util.Hashtable) StringConnection(soc.server.genericServer.StringConnection) Connection(soc.server.genericServer.Connection)

Example 40 with Connection

use of soc.server.genericServer.Connection in project JSettlers2 by jdmonin.

the class SOCServer method messageToGameExcept.

/**
 * Send a message to all the connections in a game, excluding some.
 *
 * @param gn  the name of the game
 * @param ex  the list of excluded connections; not {@code null}
 * @param mes the message
 * @param takeMon Should this method take and release
 *                game's monitor via {@link SOCGameList#takeMonitorForGame(String)} ?
 * @see #messageToGameExcept(String, Connection, SOCMessage, boolean)
 */
public void messageToGameExcept(final String gn, final List<Connection> ex, final SOCMessage mes, final boolean takeMon) {
    if (takeMon)
        gameList.takeMonitorForGame(gn);
    try {
        Vector<Connection> v = gameList.getMembers(gn);
        if (v != null) {
            // D.ebugPrintln("M2GE - "+mes);
            final String mesCmd = mes.toCmd();
            Enumeration<Connection> menum = v.elements();
            while (menum.hasMoreElements()) {
                Connection con = menum.nextElement();
                if ((con != null) && !ex.contains(con)) {
                    // currentGameEventRecord.addMessageOut(new SOCMessageRecord(mes, "SERVER", con.getData()));
                    con.put(mesCmd);
                }
            }
        }
    } catch (Exception e) {
        D.ebugPrintStackTrace(e, "Exception in messageToGameExcept");
    }
    if (takeMon)
        gameList.releaseMonitorForGame(gn);
}
Also used : StringConnection(soc.server.genericServer.StringConnection) Connection(soc.server.genericServer.Connection) MissingResourceException(java.util.MissingResourceException) EOFException(java.io.EOFException) DBSettingMismatchException(soc.server.database.DBSettingMismatchException) SocketException(java.net.SocketException) SQLException(java.sql.SQLException) IOException(java.io.IOException)

Aggregations

Connection (soc.server.genericServer.Connection)44 StringConnection (soc.server.genericServer.StringConnection)24 SQLException (java.sql.SQLException)8 MissingResourceException (java.util.MissingResourceException)8 SOCGame (soc.game.SOCGame)7 EOFException (java.io.EOFException)5 IOException (java.io.IOException)5 SocketException (java.net.SocketException)5 ArrayList (java.util.ArrayList)5 SOCPlayerElement (soc.message.SOCPlayerElement)5 DBSettingMismatchException (soc.server.database.DBSettingMismatchException)5 SOCPlayer (soc.game.SOCPlayer)4 Date (java.util.Date)3 SOCGameElements (soc.message.SOCGameElements)3 HashSet (java.util.HashSet)2 Hashtable (java.util.Hashtable)2 TimerTask (java.util.TimerTask)2 Vector (java.util.Vector)2 SOCDevCardAction (soc.message.SOCDevCardAction)2 SOCInventoryItemAction (soc.message.SOCInventoryItemAction)2