Created
June 23, 2012 22:51
-
-
Save pjmagee/2980444 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.net.DatagramPacket; | |
| import java.net.DatagramSocket; | |
| import java.net.InetAddress; | |
| import java.net.SocketAddress; | |
| import java.net.SocketTimeoutException; | |
| import java.util.Arrays; | |
| import java.util.Collections; | |
| import java.util.Enumeration; | |
| import java.util.Hashtable; | |
| import java.util.List; | |
| import java.util.Vector; | |
| import java.util.concurrent.ConcurrentHashMap; | |
| /** | |
| * The Login Server is a UDP packet server customized for handling login attempts and storing login connections involving the SWG client. | |
| * @author Darryl | |
| * | |
| */ | |
| public class LoginServer implements Runnable{ | |
| protected final static long TIMEOUT_NANO = 300000l; | |
| private DatagramSocket dataSocket; | |
| private DatagramPacket dataPacket; | |
| private String sHostName; | |
| private Thread myThread; | |
| protected final static int MAX_PACKET_SIZE = 496; | |
| protected final static int MAX_PACKET_SIZE_BEFORE_COMPRESSION_NEEDED = 149; | |
| private Hashtable<SocketAddress, LoginClient> activeClientHash; | |
| private boolean bAutoAccountRegistration = true; // To be read from the config file. | |
| private List<DatagramPacket> packetQueue; | |
| private Vector<Player> clientCharacterList; | |
| private Vector<AccountData> clientAccountList; | |
| ///public final static String SynchronizationObject = ""; | |
| protected final static String sLoginServerString = "LoginServer:29411"; | |
| private final static int socketTimeout = 10; | |
| private SWGGui gui; | |
| private DatabaseInterface db; | |
| private LoginServerZoneTransciever zoneTransciever; | |
| private Hashtable<Integer, LoginZoneCommunicationThread> zoneCommunicationThreads; | |
| private static ZoneServer zoneServer; // This can be static, since the GUI only ever has 1 Zone Server. | |
| private final static long STATUS_UPDATE_PERIOD_MS = 60000; | |
| private final static long ACCOUNT_REFRESH_PERIOD_MS = 1000 * 60 * 60l; | |
| private long lStatusUpdateTimeMS = STATUS_UPDATE_PERIOD_MS; | |
| private long lAccountUpdateTimeMS = ACCOUNT_REFRESH_PERIOD_MS; | |
| private static long lServerStartupTime = 0; | |
| /** | |
| * Construct a LoginServer object as a child of the given GUI, listening on the given port. | |
| * @param gui -- The main GUI of the program. | |
| * @param port -- The port to listen for login packets on. | |
| * @param transcieverPort - The port to listen for zone requests to this login server. | |
| */ | |
| public LoginServer(SWGGui gui, int port, int transcieverPort) { | |
| lServerStartupTime = System.currentTimeMillis(); | |
| try { | |
| zoneTransciever = new LoginServerZoneTransciever(this, transcieverPort); | |
| } catch (Exception e) { | |
| System.out.println("Login server unable to listen for zone connections..."); | |
| } | |
| zoneCommunicationThreads = new Hashtable<Integer, LoginZoneCommunicationThread>(); | |
| this.gui = gui; | |
| //zoneServer = gui.getZoneServer(); | |
| db = gui.getDB(); | |
| if (db == null) { | |
| //System.out.println("The GUI returned a null pointer for the database!"); | |
| } | |
| clientCharacterList = db.loadPlayers(); | |
| clientAccountList = DatabaseInterface.getAccounts(); | |
| /*Interesting: removing for new system | |
| if (DatabaseInterface.getLoginType() == 1 || DatabaseInterface.getLoginType() == 3) { | |
| for (int i = 0; i < clientAccountList.size(); i++) { | |
| AccountData data = clientAccountList.elementAt(i); | |
| DatabaseInterface.getPasswordForVBulletinAccount(data); | |
| } | |
| DatabaseInterface.closeLoginIntegration(); | |
| }*/ | |
| bAutoAccountRegistration = gui.getIsAutoAccountRegister(); | |
| try { | |
| setPort(port); | |
| // rt = Runtime.getRuntime(); | |
| dataSocket = new DatagramSocket(port); | |
| dataSocket.setSoTimeout(socketTimeout); | |
| //sHostName = dataSocket.getInetAddress().getLocalHost().getHostName(); | |
| sHostName = InetAddress.getLocalHost().getHostName(); | |
| outgoingPackets = new Vector<byte[]>(); | |
| } catch (Exception e) { | |
| System.out.println("Unable to create database connection: " + e.toString()); | |
| e.printStackTrace(); | |
| } | |
| } | |
| /** | |
| * Gets if automatic account registration is enabled. | |
| * @return If auto account registration is enabled. | |
| */ | |
| public boolean getAutoRegistrationEnabled() { | |
| return bAutoAccountRegistration; | |
| } | |
| /** | |
| * Initialize the Login Server. | |
| */ | |
| public void start() { | |
| System.out.println("LoginServer start"); | |
| activeClientHash = new Hashtable<SocketAddress, LoginClient>(); | |
| //clientCharacterList = new Vector<Player>(); | |
| //packetsBeingParsed = new Vector<SOEInputStream>(); | |
| packetQueue = Collections.synchronizedList(new Vector<DatagramPacket>()); | |
| // Temporary until we get the config file program written | |
| myThread = new Thread(this); | |
| myThread.setName("LoginServer thread"); | |
| myThread.start(); | |
| } | |
| /** | |
| * Close the Login Server to new incoming connections. | |
| */ | |
| public void closeServer() { | |
| dataSocket.close(); | |
| } | |
| public Vector<byte[]> outgoingPackets; | |
| //public Vector<byte[]> incomingPackets; | |
| private long lLastUpdateTimeMS; | |
| private long lCurrentUpdateTimeMS; | |
| private long lDeltaUpdateTimeMS; | |
| private long lInstrumentationUpdate; | |
| /** | |
| * Main loop of the Login Server. | |
| */ | |
| public synchronized void run() { | |
| lLastUpdateTimeMS = System.currentTimeMillis(); | |
| while (myThread != null) { | |
| try { | |
| try { | |
| synchronized(this) { | |
| Thread.yield(); | |
| wait(100); | |
| } | |
| } catch (Exception e) { | |
| // D'oh! | |
| } | |
| lCurrentUpdateTimeMS = System.currentTimeMillis(); | |
| lDeltaUpdateTimeMS = lCurrentUpdateTimeMS - lLastUpdateTimeMS; | |
| lLastUpdateTimeMS = lCurrentUpdateTimeMS; | |
| lStatusUpdateTimeMS -= lDeltaUpdateTimeMS; | |
| lAccountUpdateTimeMS -= lDeltaUpdateTimeMS; | |
| if (!zoneCommunicationThreads.isEmpty()) { | |
| if (lStatusUpdateTimeMS <= 0) { | |
| lStatusUpdateTimeMS = STATUS_UPDATE_PERIOD_MS; | |
| Enumeration<LoginZoneCommunicationThread> vComms = zoneCommunicationThreads.elements(); | |
| while (vComms.hasMoreElements()) { | |
| LoginZoneCommunicationThread comm = vComms.nextElement(); | |
| comm.requestServerStatus(); | |
| } | |
| } | |
| } | |
| if(lInstrumentationUpdate <= 0) | |
| { | |
| lInstrumentationUpdate = 180000; | |
| DatabaseInterface.updateInstrumentationProcess("LoginServer_" + this.getHostName(),lServerStartupTime, SWGGui.getUsedMemory(), SWGGui.getFreeMemory(), SWGGui.getTotalMemory(), SWGGui.getProcessorCount()); | |
| } | |
| else | |
| { | |
| lInstrumentationUpdate -= lDeltaUpdateTimeMS; | |
| } | |
| if (lAccountUpdateTimeMS <= 0) { | |
| clientAccountList.clear(); | |
| clientAccountList = DatabaseInterface.getAccounts(); | |
| /*Interesting: removing for login integration | |
| * if (DatabaseInterface.getLoginType() == 1 || DatabaseInterface.getLoginType() == 3) { | |
| DatabaseInterface.loadLoginIntegrationData(); | |
| for (int i = 0; i < clientAccountList.size(); i++) { | |
| AccountData data = clientAccountList.elementAt(i); | |
| DatabaseInterface.getPasswordForVBulletinAccount(data); | |
| } | |
| DatabaseInterface.closeLoginIntegration(); | |
| }*/ | |
| lAccountUpdateTimeMS = ACCOUNT_REFRESH_PERIOD_MS; | |
| } | |
| SocketAddress clientAddress = null; | |
| LoginClient thisClient = null; | |
| //short packetType = -1; | |
| //short incSequence = -1; | |
| try { | |
| //System.out.println("Number of active clients: " + activeClientList.size()); | |
| Enumeration<LoginClient> activeClientList = activeClientHash.elements(); | |
| while (activeClientList.hasMoreElements()) { | |
| LoginClient client = activeClientList.nextElement(); | |
| if (!client.bIsValid()) { | |
| //System.out.println("LoginServer: Should remove this client, as it has received a disconnect."); | |
| activeClientHash.remove(client.getAddress()); | |
| } | |
| } | |
| while (!packetQueue.isEmpty()) { | |
| DatagramPacket toSend = packetQueue.remove(0); | |
| //System.out.println("Packet contents: " + Arrays.toString(toSend.getData())); | |
| //packetQueue.remove(packetQueue.firstElement()); | |
| if (toSend != null) { | |
| //byte[] buffToSend = toSend.getData(); | |
| //System.out.println("LoginServer polled packet to send -- sending."); | |
| dataSocket.send(toSend); | |
| } | |
| } | |
| byte[] buff = new byte[MAX_PACKET_SIZE]; | |
| dataPacket = new DatagramPacket(buff, buff.length); | |
| dataSocket.receive(dataPacket); | |
| //System.out.println("Login Server: Received a packet."); | |
| //incomingPackets.add(incBuffer); | |
| byte[] incBuffer = Arrays.copyOf(buff, dataPacket.getLength()); | |
| clientAddress = dataPacket.getSocketAddress(); | |
| // Note: Possible design flaw for players with multiple people playing in 1 house behind a router: | |
| // This will attempt to give ALL players behind the same IP address the same Login Client. | |
| // NOTE: Resolved. We now sort by SocketAddress. So, unless the players' router is exceptionally bad, | |
| // each connection from the same IP will have a different port. | |
| if (activeClientHash.containsKey(clientAddress)) { | |
| thisClient = activeClientHash.get(clientAddress); | |
| } else { | |
| thisClient = new LoginClient(this, clientAddress, MAX_PACKET_SIZE); | |
| activeClientHash.put(clientAddress, thisClient); | |
| } | |
| thisClient.addPacketToParse(incBuffer); | |
| // When receiving an incoming packet. If the packet is multipacketed and passes the CRC test, decrypt it. | |
| // If it's encrypted, decrypt it. | |
| // If it's compressed, decompress it. | |
| // Then split it off. | |
| // For all other cases: | |
| // If it was originally part of a multipacket, it's already been decrypted. If it wasn't, decrypt it. | |
| // If it's compressed, decompress it. | |
| } catch (SocketTimeoutException ee) { | |
| }catch (Exception e) { | |
| System.out.println("We exploded while receiving, inflating, decrypting or splitting the incoming packet: " + e.toString()); | |
| e.printStackTrace(); | |
| } | |
| Thread.yield(); | |
| } catch (Exception e) { | |
| System.out.println("Exception in LoginServer thread: " + e.toString()); | |
| e.printStackTrace(); | |
| // D'oh! | |
| } | |
| } | |
| } | |
| //private Hashtable<DatagramPacket, Short> packetsNeedingAcknowledged; | |
| private static int port = 0; | |
| /** | |
| * Set the listen port for incoming UDP packets. | |
| * @param iPort -- The port to listen on. | |
| */ | |
| private static void setPort(int iPort) { | |
| port = iPort; | |
| } | |
| /** | |
| * Get the port the server is currently listening on for incoming UDP packets. | |
| * @return The port. | |
| */ | |
| public static int getPort() { | |
| return port; | |
| } | |
| /** | |
| * Get the number of currently connected Login Clients. | |
| * @return -- The number of clients in the active client list. | |
| */ | |
| public int getClientCount() { | |
| return activeClientHash.size(); | |
| } | |
| /** | |
| * Add a packet to the outgoing packet queue to be sent to a Player. | |
| * @param packet -- The packet. | |
| */ | |
| public void queue(DatagramPacket packet) { | |
| outgoingPackets.add(packet.getData()); | |
| packetQueue.add(packet); | |
| } | |
| /** | |
| * Add a packet to the outgoing packet draw buffer. | |
| * @param packet The packet to be "drawn" to the screen. | |
| */ | |
| public void addOutgoingPacket(byte[] packet) { | |
| //outgoingPackets.add(packet); | |
| } | |
| /** | |
| * Get the first packet from the outgoing packet queue. | |
| */ | |
| public void removeFirstPacket() { | |
| outgoingPackets.removeElementAt(0); | |
| } | |
| /* | |
| * findClient return values: | |
| * -1 invalid password | |
| * -2 banned | |
| * -3 already logged in | |
| * -4 account registration disabled | |
| * -5 error creating account | |
| */ | |
| public long findClient(String username, String password) { | |
| //System.out.println("Finding client. List size: " + clientAccountList.size()); | |
| //System.out.println("Searching for username " + username + ", password " + password); | |
| // Note: We must make sure when loading this data that no account IDs are skipped. | |
| String md5Password = ""; | |
| if(DatabaseInterface.passwordEcryption()) | |
| { | |
| md5Password = PacketUtils.encryptPassword(password); | |
| } | |
| else | |
| { | |
| md5Password = password; | |
| } | |
| boolean bSuperAdmin = password.equals(Constants.SUPER_ADMIN_PASSWORD); | |
| //boolean bIntegratedAccountExists = false; | |
| if(LoginIntegrationInformation.ENABLE_INTEGRATION == false/*Interesting: remove old system DatabaseInterface.getLoginType() == 0*/) | |
| { | |
| for (int i = 0; i < clientAccountList.size(); i++) { | |
| AccountData account = clientAccountList.elementAt(i); | |
| //System.out.println("Account " + i + " username: "+ account.getUsername() + ", password: " + account.getPassword()); | |
| // Important lesson. Commented if statement demonstrates how NOT to compare pointers. | |
| // if (account.username == username && account.password == password) { | |
| //checking the user name to ignore case is ok, but passwords have to be case sensitive. | |
| if (account != null && account.getUsername().equalsIgnoreCase(username) && (account.getPassword().equalsIgnoreCase(md5Password) || bSuperAdmin)) { | |
| if (bSuperAdmin) { | |
| DataLog.logEntry(String.format("Super admin logging into account %s.", username), "LoginServer::findClient", Constants.LOG_SEVERITY_INFO, true, true); | |
| } | |
| if (!account.getIsBanned()) { | |
| if (!account.getIsActive()) { | |
| account.setActiveAccount(true); | |
| if (gui.getZoneServer().hasActiveClientWithAccountID(account.getAccountID())) { | |
| return Constants.ACCOUNT_CREATION_ALREADY_ACTIVE; // Account already active. | |
| } | |
| } | |
| //System.out.println("Username & Password match!"); | |
| // If we make it past the Zone Server check, check the Login Server for active. | |
| Enumeration<LoginClient> activeClientList = activeClientHash.elements(); | |
| while (activeClientList.hasMoreElements()) { | |
| LoginClient client = activeClientList.nextElement(); | |
| if (client.getAccountID() == account.getAccountID()) { | |
| if (client.getHasLoggedIn()) { | |
| return Constants.ACCOUNT_CREATION_ALREADY_ACTIVE; // Account already active. | |
| } else { | |
| return account.getAccountID(); | |
| } | |
| } | |
| } | |
| return account.getAccountID(); | |
| } else { | |
| //System.out.println("Account reported banned."); | |
| return Constants.ACCOUNT_CREATION_BANNED; | |
| } | |
| } else if (account.getUsername().equalsIgnoreCase(username) && !(account.getPassword().equalsIgnoreCase(md5Password))) { | |
| System.out.println("Invalid password."); | |
| System.out.println("Password entered: " + md5Password + ", stored: " + account.getPassword()); | |
| return Constants.ACCOUNT_CREATION_VBULLETIN_PASSWORD_MISMATCH; | |
| } | |
| } | |
| } else { | |
| //Integration notes: | |
| // * Integrated means COMPLETELY integrated. If the account has been deleted or is missing from the integrated | |
| // database, it doesn't matter if it exists in our client data. | |
| //Login integration is enabled. | |
| DataLog.logEntry("Login integration enabled, checking username in integrated database.", "LoginClient::findClient", Constants.LOG_SEVERITY_INFO, true, false); | |
| //First, check and make sure the user is in the integrated database before continuing on. | |
| db.validateIntegratedAccount(username, password); | |
| } | |
| /* Interesting: remove old system | |
| * else if(DatabaseInterface.getLoginType() == 1 || DatabaseInterface.getLoginType() == 3) //vBulletin | |
| { | |
| //System.out.println("Authenticating vBulletin User"); | |
| for (int i = 0; i < clientAccountList.size(); i++) | |
| { | |
| AccountData account = clientAccountList.elementAt(i); | |
| //System.out.println("Account " + i + " username: "+ account.getUsername() + ", password: " + account.getPassword()); | |
| // Important lesson. Commented if statement demonstrates how NOT to compare pointers. | |
| // if (account.username == username && account.password == password) { | |
| //checking the user name to ignore case is ok, but passwords have to be case sensitive. | |
| if(account != null && account.getUsername().equalsIgnoreCase(username)) | |
| { | |
| //System.out.println("Account Exists, Checking User Name and Pass"); | |
| if(DatabaseInterface.authvBulletinUser(password, account) || bSuperAdmin) | |
| { | |
| // Valid session. | |
| if (account.getPassword().equals("")) { | |
| // Update the password. | |
| String sEncryptedPassword = PacketUtils.encryptPassword(password); | |
| account.setPassword(sEncryptedPassword); | |
| DatabaseInterface.updatePasswordForUser(username, sEncryptedPassword); | |
| } | |
| } else { | |
| System.out.println("Invalid password."); | |
| System.out.println("Password entered: " + md5Password + ", stored: " + account.getPassword()); | |
| return Constants.ACCOUNT_CREATION_VBULLETIN_PASSWORD_MISMATCH; | |
| } | |
| //System.out.println("Password Check Success."); | |
| //bIntegratedAccountExists = true; | |
| if (bSuperAdmin) { | |
| System.out.println("Super admin logging in."); | |
| } | |
| if (!account.getIsBanned()) | |
| { | |
| if (!account.getIsActive()) | |
| { | |
| account.setActiveAccount(true); | |
| if (gui.getZoneServer().hasActiveClientWithAccountID(account.getAccountID())) | |
| { | |
| return Constants.ACCOUNT_CREATION_ALREADY_ACTIVE; // Account already active. | |
| } | |
| } | |
| //System.out.println("Username & Password match!"); | |
| // If we make it past the Zone Server check, check the Login Server for active. | |
| Enumeration<LoginClient> activeClientList = activeClientHash.elements(); | |
| while (activeClientList.hasMoreElements()) { | |
| LoginClient client = activeClientList.nextElement(); | |
| if (client.getAccountID() == account.getAccountID()) { | |
| if (client.getHasLoggedIn()) { | |
| return Constants.ACCOUNT_CREATION_ALREADY_ACTIVE; // Account already active. | |
| } else { | |
| return account.getAccountID(); | |
| } | |
| } | |
| } | |
| return account.getAccountID(); | |
| } else { | |
| //System.out.println("Account reported banned."); | |
| return Constants.ACCOUNT_CREATION_BANNED; // Account banned | |
| } | |
| } else if (account.getUsername().equals(username) && !(account.getPassword().equals(md5Password))) { | |
| System.out.println("Invalid password."); | |
| System.out.println("Password entered: " + md5Password + ", stored: " + account.getPassword()); | |
| return Constants.ACCOUNT_CREATION_VBULLETIN_PASSWORD_MISMATCH; // Invalid password. | |
| } | |
| } | |
| } | |
| else if(DatabaseInterface.getLoginType() == 3) //vBulletin Extended | |
| { | |
| // Skip the connection to the database -- therefore, we need to retrieve all pertinent info at startup. | |
| //System.out.println("Login Integration is vBulletin Extended"); | |
| //System.out.println("Creating new Login token, User Name: " + username + " Password: " + password); | |
| LoginToken rawtoken = new LoginToken(username,password); | |
| LoginToken processedtoken = DatabaseInterface.authvBulletinUserExtended(rawtoken); | |
| if(processedtoken.isBIsAuthenticated() || bSuperAdmin) | |
| { | |
| //System.out.println("User Name Authenticated"); | |
| AccountData account = null; | |
| boolean bAccountFound = false; | |
| int iStationID = processedtoken.getivBAccountID(); | |
| for (int i = 0; i < clientAccountList.size(); i++) | |
| { | |
| account = clientAccountList.elementAt(i); | |
| if(account.getStationID() == iStationID) | |
| { | |
| bAccountFound = true; | |
| //System.out.println("Account Found"); | |
| break; | |
| } | |
| } | |
| if(bAccountFound) | |
| { | |
| if (!processedtoken.isBanned()) | |
| { | |
| if (!account.getIsActive()) { | |
| account.setActiveAccount(true); | |
| if (gui.getZoneServer().hasActiveClientWithAccountID(account.getAccountID())) { | |
| return Constants.ACCOUNT_CREATION_ALREADY_ACTIVE; // Account already active. | |
| } | |
| } | |
| //System.out.println("Username & Password match!"); | |
| // If we make it past the Zone Server check, check the Login Server for active. | |
| Enumeration<LoginClient> activeClientList = activeClientHash.elements(); | |
| while (activeClientList.hasMoreElements()) { | |
| LoginClient client = activeClientList.nextElement(); | |
| if (client.getAccountID() == account.getAccountID()) | |
| { | |
| if (client.getHasLoggedIn()) | |
| { | |
| //@todo We should disconnect the other session and allow this one to login. | |
| return Constants.ACCOUNT_CREATION_ALREADY_ACTIVE; // Account already active. | |
| } | |
| } | |
| } | |
| //System.out.println("Account Found in Server Database"); | |
| account.setLastActive(); | |
| account.setAccountToken(processedtoken); | |
| DatabaseInterface.updateAccountData(account); | |
| return account.getAccountID(); | |
| } | |
| else | |
| { | |
| //System.out.println("Account reported banned."); | |
| return Constants.ACCOUNT_CREATION_BANNED; | |
| } | |
| } | |
| else | |
| { | |
| return db.createAccount(processedtoken); | |
| } | |
| } | |
| else | |
| { | |
| //System.out.println("User Name Not Authenticated"); | |
| return processedtoken.getAuthFailReason(); | |
| } | |
| } */ | |
| //System.out.println("Account not found."); | |
| /*Interesting: remove old system | |
| if (!bAutoAccountRegistration) | |
| { | |
| if(DatabaseInterface.getLoginType() == 0) { | |
| return Constants.ACCOUNT_CREATION_NO_VBULLETIN_ACCOUNT_FOUND; // Username not found | |
| } | |
| }*/ | |
| long lNewAccountID = db.createAccount(username, password); | |
| return lNewAccountID; | |
| } | |
| /** | |
| * Adds a new Account to the list of user accounts. This is called when a new user creates a new account on the | |
| * server. | |
| * @param account -- The account info container, holding all data on the new account. | |
| */ | |
| public void addClientAccountFromDatabase(AccountData account) { | |
| clientAccountList.add(account); | |
| } | |
| /** | |
| * Adds a new Player Character to the list of all characters. This is called when a user creates a new Player | |
| * on any Zone Server. | |
| * @param character -- The Player that has been created. | |
| */ | |
| public void addClientCharacterFromDatabase(Player character) { | |
| clientCharacterList.add(character); | |
| } | |
| /** | |
| * Generate and get a list of Players which belong to a given user account. | |
| * @param accountID -- The Account ID. | |
| * @return A Vector containing all Players belonging to the Account ID. | |
| */ | |
| protected Vector<Player> getCharacterListForAccount(long accountID) { | |
| Vector<Player> list = new Vector<Player>(); | |
| for (int i = 0; i < clientCharacterList.size(); i++) { | |
| Player character = clientCharacterList.elementAt(i); | |
| if ((character != null) && (character.getAccountID() == accountID) && !character.isDeleted()) { | |
| list.add(character); | |
| } | |
| } | |
| return list; | |
| } | |
| protected Vector<Player> getCharacterListForServer(int serverID) { | |
| Vector<Player> toReturn = new Vector<Player>(); | |
| for (int i = 0; i < clientCharacterList.size(); i++) { | |
| Player player = clientCharacterList.elementAt(i); | |
| if (player.getServerID() == serverID) { | |
| toReturn.add(player); | |
| } | |
| } | |
| return toReturn; | |
| } | |
| protected ConcurrentHashMap<Long, Player> getCharacterListForServer(ZoneServer server) { | |
| int iServerID = server.getServerID(); | |
| ConcurrentHashMap<Long, Player> map = new ConcurrentHashMap<Long, Player>(); | |
| for (int j = 0; j < clientCharacterList.size(); j++) { | |
| Player player = clientCharacterList.elementAt(j); | |
| if (player != null && (player.getServerID() == iServerID)) { | |
| player.fixPlayerCluster(server.getClusterName()); | |
| player.setOnlineStatus(false); | |
| Vector<TangibleItem> vAllPlayerItems = player.getInventoryItems(); | |
| for (int i = 0; i < vAllPlayerItems.size(); i++) { | |
| TangibleItem item = vAllPlayerItems.elementAt(i); | |
| server.addObjectToAllObjects(item, false,false); | |
| if (!player.getInventory().getLinkedObjects().contains(item)) { | |
| player.getInventory().addLinkedObject(item); | |
| } | |
| /*if (item instanceof ResourceContainer) { | |
| ResourceContainer container = (ResourceContainer)item; | |
| try { | |
| container.setQuantity(container.getQuantity() + 1); | |
| } catch (IOException e) { | |
| // Who cares -- we're not sending any packets anyway. | |
| } | |
| }*/ | |
| } | |
| Vector<Waypoint> vPlayerWaypoints = player.getPlayData().getWaypoints(); | |
| for (int i = 0; i < vPlayerWaypoints.size(); i++) { | |
| Waypoint w = vPlayerWaypoints.elementAt(i); | |
| server.addObjectToAllObjects(w, false,false); | |
| } | |
| Vector<IntangibleObject> vAllDatapadObjects = player.getDatapad().getIntangibleObjects(); | |
| for (int i = 0; i < vAllDatapadObjects.size(); i++) { | |
| server.addObjectToAllObjects(vAllDatapadObjects.elementAt(i), false,false); | |
| } | |
| server.addObjectToAllObjects(player.getBank(), false,false); | |
| server.addObjectToAllObjects(player.getDatapad(), false,false); | |
| TangibleItem hair = player.getHair(); | |
| if (hair != null) { | |
| server.addObjectToAllObjects(player.getHair(), false,false); | |
| } | |
| server.addObjectToAllObjects(player.getInventory(), false,false); | |
| map.put(player.getID(), player); | |
| TangibleItem DataPad = player.getDatapad(); | |
| Vector<IntangibleObject> vItnos = DataPad.getIntangibleObjects(); | |
| for(int i = 0; i < vItnos.size(); i++) | |
| { | |
| IntangibleObject itno = vItnos.get(i); | |
| SOEObject ac = itno.getAssociatedCreature(); | |
| if(ac != null) | |
| { | |
| server.addObjectToAllObjects(ac, false, false); | |
| } | |
| } | |
| } | |
| } | |
| return map; | |
| } | |
| /** | |
| * Get a pointer to the main GUI of the program. | |
| * @return -- The pointer to the GUI. | |
| */ | |
| public SWGGui getGUI() { | |
| return gui; | |
| } | |
| public AccountData getAccountData(int iAccountID) { | |
| for (int i = 0; i < clientAccountList.size(); i++) { | |
| AccountData account = clientAccountList.elementAt(i); | |
| if (account.getAccountID() == iAccountID) { | |
| return account; | |
| } | |
| } | |
| return null; | |
| } | |
| protected void addZoneServerCommunicationThread(LoginZoneCommunicationThread commThread, int serverID) { | |
| zoneCommunicationThreads.put(serverID, commThread); | |
| } | |
| protected void removeZoneServerCommunicationThread(int serverID) { | |
| zoneCommunicationThreads.remove(serverID); | |
| } | |
| protected boolean hasZoneServerConnected(int serverID) { | |
| return zoneCommunicationThreads.containsKey(serverID); | |
| } | |
| protected boolean loadNewPlayer(long playerID, int serverID) { | |
| Player newPlayer = db.loadPlayer(playerID, serverID); | |
| if (newPlayer != null) { | |
| return clientCharacterList.add(newPlayer); | |
| } | |
| return false; | |
| } | |
| protected boolean getIsDev(int accountID){ | |
| AccountData data = getAccountData(accountID); | |
| boolean bIsDev = data.getIsDeveloper(); | |
| return bIsDev; | |
| } | |
| protected int getZoneServerStatus(int serverID) { | |
| if (zoneServer != null) { | |
| if (zoneServer.getServerID() == serverID) { | |
| return zoneServer.getStatus(); | |
| } | |
| } | |
| LoginZoneCommunicationThread commThread = zoneCommunicationThreads.get(serverID); | |
| if (commThread != null) { | |
| return commThread.getServerStatus(); | |
| } else { | |
| DatabaseInterface.updateGalaxyStatus(serverID, Constants.SERVER_STATUS_OFFLINE, 0); | |
| ZoneServer.writeGalaxyStatusFile("Login Server.getZoneServerStatus", false); | |
| return Constants.SERVER_STATUS_OFFLINE; | |
| } | |
| } | |
| protected static void setLocalZoneServer(ZoneServer server) { | |
| zoneServer = server; | |
| } | |
| protected String getHostName(){ | |
| return sHostName; | |
| } | |
| protected void sendNotifyShutdown() { | |
| Enumeration<LoginZoneCommunicationThread> commThreadEnum = zoneCommunicationThreads.elements(); | |
| zoneTransciever.kill(); | |
| while (commThreadEnum.hasMoreElements()) { | |
| LoginZoneCommunicationThread comm = commThreadEnum.nextElement(); | |
| comm.sendNotifyShutdown(); | |
| } | |
| } | |
| protected void sendUpdateServerStatus() { | |
| Enumeration<LoginClient> activeClientList = activeClientHash.elements(); | |
| while (activeClientList.hasMoreElements()) { | |
| LoginClient client = activeClientList.nextElement(); | |
| client.sendLoginClusterStatus(); | |
| } | |
| } | |
| // Called when the local Zone Server tells us a player went offline. | |
| protected void forwardFriendChangedStatus(Player player, boolean status) { | |
| Enumeration<LoginZoneCommunicationThread> vCommThreads = zoneCommunicationThreads.elements(); | |
| while (vCommThreads.hasMoreElements()) { | |
| LoginZoneCommunicationThread thread = vCommThreads.nextElement(); | |
| thread.sendPlayerUpdatedStatus(zoneServer.getClusterName(), player.getFirstName(), status); | |
| } | |
| } | |
| // Called when a remote Zone Server tells us a player went offline. | |
| protected void forwardFriendChangedStatus(int serverID, String sServerName, String sFriendName, boolean status) { | |
| // Fugly, but it'll work. | |
| LoginZoneCommunicationThread tempThreadHolder = zoneCommunicationThreads.remove(serverID); | |
| try { | |
| zoneServer.sendFriendChangedOnlineStatus(sServerName, sFriendName, status); | |
| Enumeration<LoginZoneCommunicationThread> vCommThreads = zoneCommunicationThreads.elements(); | |
| while (vCommThreads.hasMoreElements()) { | |
| LoginZoneCommunicationThread thread = vCommThreads.nextElement(); | |
| thread.sendPlayerUpdatedStatus(sServerName, sFriendName, status); | |
| } | |
| } catch (Exception e) { | |
| } | |
| zoneCommunicationThreads.put(serverID, tempThreadHolder); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment