📄 server.java
字号:
colorUsed[otherPlayer.getColorIndex()] = true; } } if (null != player && colorUsed[player.getColorIndex()]) { // find a replacement color; for (int i = 0; i < colorUsed.length; i++) { if (!colorUsed[i]) { player.setColorIndex(i); break; } } } } /** * Called when it's been determined that an actual player * disconnected. Notifies the other players and does the appropriate * housekeeping. */ void disconnected(Player player) { int phase = game.getPhase(); // in the lounge, just remove all entities for that player if (phase == IGame.PHASE_LOUNGE) { removeAllEntitesOwnedBy(player); } // if a player has active entities, he becomes a ghost // except the VICTORY_PHASE when the dosconnected // player is most likely the Bot disconnected after receiving // the COMMAND_END_OF_GAME command // see the Bug 1225949. // TODO Perhaps there is a better solution to handle the Bot disconnect if (game.getEntitiesOwnedBy(player) > 0 && phase != IGame.PHASE_VICTORY) { player.setGhost(true); player.setDone(true); send(createPlayerUpdatePacket(player.getId())); } else { game.removePlayer(player.getId()); send(new Packet(Packet.COMMAND_PLAYER_REMOVE, new Integer(player.getId()))); } // make sure the game advances if ( game.phaseHasTurns(game.getPhase()) && null != game.getTurn() ) { if ( game.getTurn().isValid( player.getId(), game ) ) { sendGhostSkipMessage( player ); } } else { checkReady(); } // notify other players sendServerChat(player.getName() + " disconnected."); // log it System.out.println("s: removed player " + player.getName()); // Reset the game after Elvis has left the building. if ( 0 == game.getNoOfPlayers() ) { resetGame(); } } /** * Checks each player to see if he has no entities, and if true, sets the * observer flag for that player. An exception is that there are no * observers during the lounge phase. */ public void checkForObservers() { for (Enumeration e = game.getPlayers(); e.hasMoreElements(); ) { Player p = (Player)e.nextElement(); p.setObserver(game.getEntitiesOwnedBy(p) < 1 && game.getPhase() != IGame.PHASE_LOUNGE); } } /** * Reset the game back to the lounge. * * TODO: couldn't this be a hazard if there are other things executing at * the same time? */ public void resetGame() { // remove all entities game.reset(); send(createEntitiesPacket()); send(new Packet(Packet.COMMAND_SENDING_MINEFIELDS, new Vector())); //remove ghosts ArrayList<Player> ghosts = new ArrayList(); for(Enumeration<Player> players = game.getPlayers(); players.hasMoreElements();) { Player p = players.nextElement(); if(p.isGhost()) { ghosts.add(p); } } for(Player p:ghosts) { game.removePlayer(p.getId()); send(new Packet(Packet.COMMAND_PLAYER_REMOVE, new Integer(p.getId()))); } // reset all players resetPlayersDone(); transmitAllPlayerDones(); // Write end of game to stdout so controlling scripts can rotate logs. SimpleDateFormat format = new SimpleDateFormat ( "yyyy-MM-dd HH:mm:ss z" ); System.out.print( format.format(new Date()) ); System.out.println( " END OF GAME" ); changePhase(IGame.PHASE_LOUNGE); } /** * automatically save the game */ public void autoSave() { String fileName = "autosave"; if (PreferenceManager.getClientPreferences().stampFilenames()) { fileName = StringUtil.addDateTimeStamp(fileName); } saveGame(fileName,game.getOptions().booleanOption("autosave_msg")); } /** * save the game and send it to the sepecified connection * @param connId The <code>int</code> connection id to send to * @param sFile The <code>String</code> filename to use */ public void sendSaveGame (int connId, String sFile) { saveGame(sFile, false); String sFinalFile = sFile; if (!sFinalFile.endsWith(".sav")) { sFinalFile = sFile + ".sav"; } String localFile = "savegames" + File.separator + sFinalFile; File f = new File(localFile); try { ObjectInputStream ois = new ObjectInputStream( new FileInputStream(f)); send(connId,new Packet(Packet.COMMAND_SEND_SAVEGAME, new Object[] {sFinalFile, ois.readObject()})); sendChat(connId,"***Server","Savegame has been sent to you."); ois.close(); } catch (Exception e) { System.err.println("Unable to load file: " + f); e.printStackTrace(); } } /** * save the game * @param sFile The <code>String</code> filename to use * @param sendChat A <code>boolean</code> value wether or not to announce * the saving to the server chat. */ public void saveGame(String sFile, boolean sendChat) { String sFinalFile = sFile; if (!sFinalFile.endsWith(".sav")) { sFinalFile = sFile + ".sav"; } try { File sDir = new File("savegames"); if (!sDir.exists()) { sDir.mkdir(); } sFinalFile = sDir + File.separator + sFinalFile; ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream(sFinalFile)); oos.writeObject(game); oos.flush(); oos.close(); } catch (Exception e) { System.err.println("Unable to save file: " + sFinalFile); e.printStackTrace(); } if (sendChat) sendChat("MegaMek", "Game saved to " + sFinalFile); } /** * save the game * @param sFile The <code>String</code> filename to use */ public void saveGame(String sFile) { saveGame(sFile,true); } /** * load the game * @param f The <code>File</code> to load * @return A <code>boolean</code> value wether or not the loading was successfull */ public boolean loadGame(File f) { System.out.println("s: loading saved game file '"+f+'\''); try { ObjectInputStream ois = new ObjectInputStream( new FileInputStream(f)); game = (IGame)ois.readObject(); ois.close(); } catch (Exception e) { System.err.println("Unable to load file: " + f); e.printStackTrace(); return false; } // a bit redundant, but there's some initialization code there setGame(game); return true; } /** * Shortcut to game.getPlayer(id) */ public Player getPlayer(int id) { return game.getPlayer(id); } /** * Removes all entities owned by a player. Should only be called when it * won't cause trouble (the lounge, for instance, or between phases.) * @param player whose entites are to be removed */ private void removeAllEntitesOwnedBy(Player player) { Vector toRemove = new Vector(); for (Enumeration e = game.getEntities(); e.hasMoreElements();) { final Entity entity = (Entity)e.nextElement(); if (entity.getOwner().equals(player)) { toRemove.addElement(entity); } } for (Enumeration e = toRemove.elements(); e.hasMoreElements();) { final Entity entity = (Entity)e.nextElement(); int id = entity.getId(); game.removeEntity(id, IEntityRemovalConditions.REMOVE_NEVER_JOINED); send(createRemoveEntityPacket(id, IEntityRemovalConditions.REMOVE_NEVER_JOINED)); } } /** * a shorter name for getConnection() */ private Connection getClient(int connId) { return getConnection(connId); } /** * Returns a connection, indexed by id */ public Enumeration getConnections() { return connections.elements(); } /** * Returns a connection, indexed by id */ public Connection getConnection(int connId) { return (Connection)connectionIds.get(new Integer(connId)); } /** * Returns a pending connection */ private Connection getPendingConnection(int connId) { for (Enumeration i=connectionsPending.elements();i.hasMoreElements();){ final Connection conn = (Connection)i.nextElement(); if (conn.getId() == connId) { return conn; } } return null; } /** * Called at the beginning of each game round to reset values on this * entity that are reset every round */ private void resetEntityRound() { for (Enumeration e = game.getEntities(); e.hasMoreElements();) { Entity entity = (Entity)e.nextElement(); entity.newRound(game.getRoundCount()); } } /** * Called at the beginning of each phase. Sets and resets * any entity parameters that need to be reset. */ private void resetEntityPhase(int phase) { // first, mark doomed entities as destroyed and flag them Vector toRemove = new Vector(0, 10); for (Enumeration e = game.getEntities(); e.hasMoreElements();) { final Entity entity = (Entity)e.nextElement(); if (entity.crew.isDoomed()) { entity.crew.setDead(true); entity.setDestroyed(true); } if (entity.isDoomed()) { entity.setDestroyed(true); // Is this unit swarming somebody? Better let go before // it's too late. final int swarmedId = entity.getSwarmTargetId(); if ( Entity.NONE != swarmedId ) { final Entity swarmed = game.getEntity( swarmedId ); swarmed.setSwarmAttackerId( Entity.NONE ); entity.setSwarmTargetId( Entity.NONE ); Report r = new Report(5165); r.subject = swarmedId; r.addDesc(swarmed); addReport(r); entityUpdate( swarmedId ); } } if (entity.isDestroyed() || entity.getCrew().isDead()) { toRemove.addElement(entity); } } // actually remove all flagged entities for (Enumeration e = toRemove.elements(); e.hasMoreElements();) { final Entity entity = (Entity)e.nextElement(); int condition = IEntityRemovalConditions.REMOVE_SALVAGEABLE; if ( !entity.isSalvage() ) { condition = IEntityRemovalConditions.REMOVE_DEVASTATED; } entityUpdate(entity.getId()); game.removeEntity(entity.getId(), condition); send( createRemoveEntityPacket(entity.getId(), condition) ); } // do some housekeeping on all the remaining for (Enumeration e = game.getEntities(); e.hasMoreElements();) { final Entity entity = (Entity)e.nextElement(); entity.applyDamage(); entity.reloadEmptyWeapons(); // reset damage this phase entity.damageThisPhase = 0; entity.engineHitsThisRound = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -