diff --git a/scripts/commands/server.py b/scripts/commands/server.py index a55f433a..6ba1dc5b 100644 --- a/scripts/commands/server.py +++ b/scripts/commands/server.py @@ -29,5 +29,7 @@ def run(core, actor, target, commandString): core.setGalaxyStatus(3) if command == 'unlockServer': core.setGalaxyStatus(2) + if command == 'info': + actor.sendSystemMessage(str(core.getActiveZoneClients()) + ' online characters.', 0) return diff --git a/src/main/NGECore.java b/src/main/NGECore.java index baf74bb6..cc87338e 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -35,6 +35,8 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.apache.mina.core.service.IoHandler; + +import protocol.swg.ChatSystemMessage; import net.engio.mbassy.bus.config.BusConfiguration; import resources.common.RadialOptions; import resources.common.ThreadMonitor; @@ -108,6 +110,7 @@ public class NGECore { private Config config = null; + private volatile boolean isShuttingDown = false; private ConcurrentHashMap clients = new ConcurrentHashMap(); @@ -503,5 +506,39 @@ public class NGECore { return eventBusConfig; } + public void initiateShutdown() { + if(isShuttingDown) + return; + try { + + for(int minutes = 15; minutes > 1; minutes--) { + simulationService.notifyAllClients(new ChatSystemMessage("The server will be shutting down soon. Please find a safe place to logout. (" + minutes + " minutes left)", (byte) 0 ).serialize()); + Thread.sleep(60000); + } + setGalaxyStatus(3); + simulationService.notifyAllClients(new ChatSystemMessage("The server will be shutting down soon. Please find a safe place to logout. (" + 1 + " minutes left)", (byte) 0 ).serialize()); + Thread.sleep(30000); + simulationService.notifyAllClients(new ChatSystemMessage("You will be disconnected in 30 seconds so the server can perform a final save before shutting down. Please find a safe place to logout now.", (byte) 0 ).serialize()); + Thread.sleep(20000); + simulationService.notifyAllClients(new ChatSystemMessage("You will be disconnected in 10 seconds so the server can perform a final save before shutting down. Please find a safe place to logout now.", (byte) 0 ).serialize()); + Thread.sleep(10000); + simulationService.notifyAllClients(new ChatSystemMessage("You will now be disconnected so the server can perform a final save before shutting down.", (byte) 0 ).serialize()); + + synchronized(getActiveConnectionsMap()) { + for(Client client : getActiveConnectionsMap().values()) { + client.getSession().close(true); + } + } + + System.exit(0); + + } catch (InterruptedException e) { + e.printStackTrace(); + } + + + + } + } diff --git a/src/protocol/swg/ClientPermissionsMessage.java b/src/protocol/swg/ClientPermissionsMessage.java index b2f7dc22..8a2ba6de 100644 --- a/src/protocol/swg/ClientPermissionsMessage.java +++ b/src/protocol/swg/ClientPermissionsMessage.java @@ -28,11 +28,14 @@ import org.apache.mina.core.buffer.IoBuffer; public class ClientPermissionsMessage extends SWGMessage { - public ClientPermissionsMessage() { + private int characterSlotsOpen; + + public ClientPermissionsMessage(int characterSlotsOpen) { + if(characterSlotsOpen < 0) + characterSlotsOpen = 0; + this.characterSlotsOpen = characterSlotsOpen; operandCount = 5; opcode = 0xE00730E5; - - data = new byte[] { (byte)0x01, (byte)0x01, (byte)0x00, (byte)0x01 }; } public void deserialize(IoBuffer data) { @@ -44,9 +47,11 @@ public class ClientPermissionsMessage extends SWGMessage { result.putShort(operandCount); result.putInt(opcode); - result.put(data); - result.flip(); + result.put((byte) 1); + result.put((byte) characterSlotsOpen); + result.put((byte) 0); + result.put((byte) 1); - return result; + return result.flip(); } } diff --git a/src/resources/objects/player/PlayerObject.java b/src/resources/objects/player/PlayerObject.java index 2a56fe85..db033e93 100644 --- a/src/resources/objects/player/PlayerObject.java +++ b/src/resources/objects/player/PlayerObject.java @@ -41,7 +41,7 @@ import engine.resources.scene.Planet; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; -@Persistent(version=0) +@Persistent(version=3) public class PlayerObject extends IntangibleObject { // PLAY 3 diff --git a/src/resources/z/exp/objects/waypoint/WaypointObject.java b/src/resources/z/exp/objects/waypoint/WaypointObject.java index df08f5ca..6539e172 100644 --- a/src/resources/z/exp/objects/waypoint/WaypointObject.java +++ b/src/resources/z/exp/objects/waypoint/WaypointObject.java @@ -37,7 +37,7 @@ import engine.resources.scene.Planet; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; -@Persistent +@Persistent(version=0) public class WaypointObject extends IntangibleObject implements IDelta { public static final byte BLUE, GREEN, ORANGE, YELLOW, PURPLE, WHITE, MULTICOLOR; diff --git a/src/services/CharacterService.java b/src/services/CharacterService.java index 9d265f47..40e7ded9 100644 --- a/src/services/CharacterService.java +++ b/src/services/CharacterService.java @@ -447,5 +447,19 @@ public class CharacterService implements INetworkDispatch { // TODO Auto-generated method stub } + + public int getNumberOfCharacters(int accountId) { + PreparedStatement preparedStatement; + int characters = 0; + try { + preparedStatement = databaseConnection.preparedStatement("SELECT * FROM characters WHERE \"accountId\"=" + accountId + ""); + ResultSet resultSet = preparedStatement.executeQuery(); + while(resultSet.next() && !resultSet.isClosed()) + characters++; + } catch (SQLException e) { + e.printStackTrace(); + } + return characters; + } } diff --git a/src/services/ConnectionService.java b/src/services/ConnectionService.java index 9acee192..8619f799 100644 --- a/src/services/ConnectionService.java +++ b/src/services/ConnectionService.java @@ -70,7 +70,6 @@ public class ConnectionService implements INetworkDispatch { @Override public void handlePacket(IoSession session, IoBuffer data) throws Exception { - System.out.println("xx"); data = data.order(ByteOrder.LITTLE_ENDIAN); ClientIdMsg clientIdMsg = new ClientIdMsg(); data.position(0); @@ -96,13 +95,12 @@ public class ConnectionService implements INetworkDispatch { client.setSessionKey(clientIdMsg.getSessionKey()); client.setGM(core.loginService.checkForGmPermission((int) resultSet.getLong("accountId"))); AccountFeatureBits accountFeatureBits = new AccountFeatureBits(); - ClientPermissionsMessage clientPermissionsMessage = new ClientPermissionsMessage(); + ClientPermissionsMessage clientPermissionsMessage = new ClientPermissionsMessage(2 - core.characterService.getNumberOfCharacters((int) resultSet.getLong("accountId"))); session.write(new HeartBeatMessage().serialize()); session.write(accountFeatureBits.serialize()); session.write(clientPermissionsMessage.serialize()); preparedStatement.close(); - System.out.println("zyx"); } else { System.out.println("Cant get login session"); }