void handleLoginRandTriggerMessage(AccountClient client, MessageIn msg) { string salt=getRandomString(4); string username=msg.readString(); ISL.Server.Account.Account acc=Program.storage.getAccount(username); if(acc!=null) { acc.setRandomSalt(salt); mPendingAccounts.Add(acc); } MessageOut reply=new MessageOut(Protocol.APMSG_LOGIN_RNDTRGR_RESPONSE); reply.writeString(salt); client.send(reply); }
void handleRegisterMessage(AccountClient client, MessageIn msg) { int clientVersion=msg.readInt32(); string username=msg.readString(); string password=msg.readString(); string email=msg.readString(); string captcha=msg.readString(); MessageOut reply=new MessageOut(Protocol.APMSG_REGISTER_RESPONSE); if(client.status!=AccountClientStatus.CLIENT_LOGIN) { reply.writeInt8((int)ErrorMessage.ERRMSG_FAILURE); } else if(!mRegistrationAllowed) { reply.writeInt8((int)ErrorMessage.ERRMSG_FAILURE); } else if(clientVersion<ManaServ.PROTOCOL_VERSION) { reply.writeInt8((int)Register.REGISTER_INVALID_VERSION); } else if(Program.stringFilter.findDoubleQuotes(username) ||Program.stringFilter.findDoubleQuotes(email) ||username.Length<mMinNameLength ||username.Length>mMaxNameLength ||!Program.stringFilter.isEmailValid(email) ||!Program.stringFilter.filterContent(username)) { reply.writeInt8((int)ErrorMessage.ERRMSG_INVALID_ARGUMENT); } else if(Program.storage.doesUserNameExist(username)) { reply.writeInt8((int)Register.REGISTER_EXISTS_USERNAME); } else if(Program.storage.doesEmailAddressExist(SHA256.HashString(email))) { reply.writeInt8((int)Register.REGISTER_EXISTS_EMAIL); } else if(!checkCaptcha(client, captcha)) { reply.writeInt8((int)Register.REGISTER_CAPTCHA_WRONG); } else { ISL.Server.Account.Account acc=new ISL.Server.Account.Account(); acc.setName(username); acc.setPassword(SHA256.HashString(password)); // We hash email server-side for additional privacy // we ask for it again when we need it and verify it // through comparing it with the hash. acc.setEmail(SHA256.HashString(email)); acc.setLevel((int)AccessLevel.AL_PLAYER); // Set the date and time of the account registration, and the last login DateTime regdate=DateTime.Now; acc.setRegistrationDate(regdate); acc.setLastLogin(regdate); Program.storage.addAccount(acc); reply.writeInt8((int)ErrorMessage.ERRMSG_OK); addServerInfo(reply); // Associate account with connection client.setAccount(acc); client.status=AccountClientStatus.CLIENT_CONNECTED; } client.send(reply); }
void handleLoginMessage(AccountClient client, MessageIn msg) { MessageOut reply=new MessageOut(Protocol.APMSG_LOGIN_RESPONSE); //Überprüfung ob es sich um einen Login Request handelt if(client.status!=AccountClientStatus.CLIENT_LOGIN) { reply.writeInt8((int)ErrorMessage.ERRMSG_FAILURE); client.send(reply); return; } int clientVersion=msg.readInt32(); if(clientVersion<ManaServ.PROTOCOL_VERSION) { reply.writeInt8((int)Login.LOGIN_INVALID_VERSION); client.send(reply); return; } // Check whether the last login attempt for this IP is still too fresh IPAddress address=client.getIP(); DateTime now=DateTime.Now; if(mLastLoginAttemptForIP.ContainsKey(address)) //TODO Schauen ob der Vergleich gegen das IPAdress Objekt funktioniert { DateTime lastAttempt=mLastLoginAttemptForIP[address]; lastAttempt.AddSeconds(1); //TODO schauen ob hier im Original wirklich Sekunden gemeint sind if(now<lastAttempt) { reply.writeInt8((int)Login.LOGIN_INVALID_TIME); client.send(reply); return; } } mLastLoginAttemptForIP[address]=now; string username=msg.readString(); string password=msg.readString(); if(Program.stringFilter.findDoubleQuotes(username)) { reply.writeInt8((int)ErrorMessage.ERRMSG_INVALID_ARGUMENT); client.send(reply); return; } uint maxClients=(uint)Configuration.getValue("net_maxClients", 1000); if(getClientCount()>=maxClients) { reply.writeInt8((int)ErrorMessage.ERRMSG_SERVER_FULL); client.send(reply); return; } // Check if the account exists ISL.Server.Account.Account acc=null; foreach(ISL.Server.Account.Account tmp in mPendingAccounts) { if(tmp.getName()==username) { acc=tmp; break; } } mPendingAccounts.Remove(acc); //TODO Überprüfen ob SHA256 das gewünschte Ergebniss liefert if(acc!=null) { if(SHA256.HashString(acc.getPassword()+acc.getRandomSalt())!=password) { reply.writeInt8((int)ErrorMessage.ERRMSG_INVALID_ARGUMENT); client.send(reply); //delete acc; return; } } if(acc.getLevel()==(int)AccessLevel.AL_BANNED) { reply.writeInt8((int)Login.LOGIN_BANNED); client.send(reply); //delete acc; return; } // The client successfully logged in... // Set lastLogin date of the account. DateTime login=DateTime.Now; acc.setLastLogin(login); Program.storage.updateLastLogin(acc); // Associate account with connection. client.setAccount(acc); client.status=AccountClientStatus.CLIENT_CONNECTED; reply.writeInt8((int)ErrorMessage.ERRMSG_OK); addServerInfo(reply); client.send(reply); // Acknowledge login // Return information about available characters Dictionary<uint, Character> chars=acc.getCharacters(); // Send characters list foreach(ISL.Server.Account.Character character in chars.Values) { sendCharacterData(client, character); } }
void handleCharacterSelectMessage(AccountClient client, MessageIn msg) { MessageOut reply=new MessageOut(Protocol.APMSG_CHAR_SELECT_RESPONSE); ISL.Server.Account.Account acc=client.getAccount(); if(acc==null) { reply.writeInt8((int)ErrorMessage.ERRMSG_NO_LOGIN); client.send(reply); return; // not logged in } int slot=msg.readInt8(); Dictionary<uint, Character> chars=acc.getCharacters(); if(chars.ContainsKey((uint)slot)==false) { // Invalid char selection reply.writeInt8((int)ErrorMessage.ERRMSG_INVALID_ARGUMENT); client.send(reply); return; } Character selectedChar=chars[(uint)slot]; string address; int port; int charMapId=selectedChar.getMapId(); bool gameServerHasMap=GameServerHandler.getGameServerFromMap(charMapId, out address, out port); if(!gameServerHasMap) { Logger.Write(LogLevel.Error, "Character Selection: No game server for map #{0}", selectedChar.getMapId()); reply.writeInt8((int)ErrorMessage.ERRMSG_FAILURE); client.send(reply); return; } reply.writeInt8((int)ErrorMessage.ERRMSG_OK); Logger.Write(LogLevel.Debug, "{0} is trying to enter the servers.", selectedChar.getName()); string magic_token=Various.GetUniqueID(); reply.writeString(magic_token); reply.writeString(address); reply.writeInt16(port); // Give address and port for the chat server reply.writeString(Configuration.getValue("net_chatHost", "localhost")); // When the chatListenToClientPort is set, we use it. // Otherwise, we use the accountListenToClientPort + 2 if the option is set. // If neither, the DEFAULT_SERVER_PORT + 2 is used. int alternativePort=Configuration.getValue("net_accountListenToClientPort", Configuration.DEFAULT_SERVER_PORT)+2; reply.writeInt16(Configuration.getValue("net_chatListenToClientPort", alternativePort)); GameServerHandler.registerClient(magic_token, selectedChar); //TODO Überprüfen ob diese beiden Funktionen funktionieren ChatHandler.registerChatClient(magic_token, selectedChar.getName(), acc.getLevel()); client.send(reply); // log transaction Transaction trans=new Transaction(); trans.mCharacterId=(uint)selectedChar.getDatabaseID(); trans.mAction=(uint)TransactionMembers.TRANS_CHAR_SELECTED; Program.storage.addTransaction(trans); }
void handleCharacterCreateMessage(AccountClient client, MessageIn msg) { string name=msg.readString(); int hairStyle=msg.readInt8(); int hairColor=msg.readInt8(); int gender=msg.readInt8(); // Avoid creation of character from old clients. // int slot=-1; // if(msg.getUnreadLength()>7) // { int slot=msg.readInt8(); // } MessageOut reply=new MessageOut(Protocol.APMSG_CHAR_CREATE_RESPONSE); ISL.Server.Account.Account acc=client.getAccount(); if(acc==null) { reply.writeInt8((byte)ErrorMessage.ERRMSG_NO_LOGIN); } else if(!Program.stringFilter.filterContent(name)) { reply.writeInt8((byte)ErrorMessage.ERRMSG_INVALID_ARGUMENT); } else if(Program.stringFilter.findDoubleQuotes(name)) { reply.writeInt8((byte)ErrorMessage.ERRMSG_INVALID_ARGUMENT); } else if(hairStyle>mNumHairStyles) { reply.writeInt8((byte)Create.CREATE_INVALID_HAIRSTYLE); } else if(hairColor>mNumHairColors) { reply.writeInt8((byte)Create.CREATE_INVALID_HAIRCOLOR); } else if(gender>mNumGenders) { reply.writeInt8((byte)Create.CREATE_INVALID_GENDER); } else if((name.Length<mMinNameLength)|| (name.Length>mMaxNameLength)) { reply.writeInt8((byte)ErrorMessage.ERRMSG_INVALID_ARGUMENT); } else { if(Program.storage.doesCharacterNameExist(name)) { reply.writeInt8((byte)Create.CREATE_EXISTS_NAME); client.send(reply); return; } // An account shouldn't have more // than <account_maxCharacters> characters. Dictionary<uint, ISL.Server.Account.Character> chars=acc.getCharacters(); if(slot<1||slot>mMaxCharacters||!acc.isSlotEmpty((uint)slot)) { reply.writeInt8((byte)Create.CREATE_INVALID_SLOT); client.send(reply); return; } if((int)chars.Count>=mMaxCharacters) { reply.writeInt8((byte)Create.CREATE_TOO_MUCH_CHARACTERS); client.send(reply); return; } // TODO: Add race, face and maybe special attributes. // Customization of character's attributes... List<int> attributes=new List<int>(); //std::vector<int>(mModifiableAttributes.size(), 0); for(uint i = 0;i < mModifiableAttributes.Count;++i) { attributes.Add(msg.readInt16()); } int totalAttributes=0; for(uint i = 0;i < mModifiableAttributes.Count;++i) { // For good total attributes check. totalAttributes+=attributes[(int)i]; // For checking if all stats are >= min and <= max. if(attributes[(int)i]<mAttributeMinimum ||attributes[(int)i]>mAttributeMaximum) { reply.writeInt8((byte)Create.CREATE_ATTRIBUTES_OUT_OF_RANGE); client.send(reply); return; } } if(totalAttributes>mStartingPoints) { reply.writeInt8((byte)Create.CREATE_ATTRIBUTES_TOO_HIGH); } else if(totalAttributes<mStartingPoints) { reply.writeInt8((byte)Create.CREATE_ATTRIBUTES_TOO_LOW); } else { Character newCharacter=new Character(name); // Set the initial attributes provided by the client for(uint i = 0;i < mModifiableAttributes.Count;++i) { //TODO schauen was hier genau passieren muss //newCharacter.mAttributes.Add((uint)(mModifiableAttributes[(int)i]), mModifiableAttributes[i]); //newCharacter.mAttributes.Add((uint)mModifiableAttributes[(int)i], attributes[(int)i]); } foreach(KeyValuePair<uint, Attribute> defaultAttributePair in mDefaultAttributes) { //TODO schauen was hier genau passieren muss // newCharacter.mAttributes.Add(defaultAttributePair.Key, defaultAttributePair.Value); } newCharacter.setAccount(acc); newCharacter.setCharacterSlot((uint)slot); newCharacter.setGender(gender); newCharacter.setHairStyle(hairStyle); newCharacter.setHairColor(hairColor); newCharacter.setMapId(Configuration.getValue("char_startMap", 1)); Point startingPos=new Point(Configuration.getValue("char_startX", 1024), Configuration.getValue("char_startY", 1024)); newCharacter.setPosition(startingPos); acc.addCharacter(newCharacter); Logger.Write(LogLevel.Information, "Character {0} was created for {1}'s account.", name, acc.getName()); Program.storage.flush(acc); // flush changes // log transaction Transaction trans=new Transaction(); trans.mCharacterId=(uint)newCharacter.getDatabaseID(); trans.mAction=(uint)TransactionMembers.TRANS_CHAR_CREATE; trans.mMessage=acc.getName()+" created character "; trans.mMessage+="called "+name; Program.storage.addTransaction(trans); reply.writeInt8((byte)ErrorMessage.ERRMSG_OK); client.send(reply); // Send new characters infos back to client sendCharacterData(client, chars[(uint)slot]); return; } } client.send(reply); }
void tokenMatched(AccountClient client, int accountID) { MessageOut reply=new MessageOut(Protocol.APMSG_RECONNECT_RESPONSE); //Associate account with connection. ISL.Server.Account.Account acc=Program.storage.getAccount(accountID); client.setAccount(acc); client.status=AccountClientStatus.CLIENT_CONNECTED; reply.writeInt8((int)ErrorMessage.ERRMSG_OK); client.send(reply); // Return information about available characters Dictionary<uint, Character> chars=acc.getCharacters(); // Send characters list foreach(Character character in chars.Values) { sendCharacterData(client, character); } }
void sendCharacterData(AccountClient client, Character ch) { MessageOut charInfo=new MessageOut(Protocol.APMSG_CHAR_INFO); charInfo.writeInt8((int)ch.getCharacterSlot()); charInfo.writeString(ch.getName()); charInfo.writeInt8(ch.getGender()); charInfo.writeInt8(ch.getHairStyle()); charInfo.writeInt8(ch.getHairColor()); charInfo.writeInt16(ch.getLevel()); charInfo.writeInt16(ch.getCharacterPoints()); charInfo.writeInt16(ch.getCorrectionPoints()); foreach(KeyValuePair<uint, AttributeValue> at in ch.mAttributes) { charInfo.writeInt32((int)at.Key); charInfo.writeInt32((int)(at.Value.@base*256)); charInfo.writeInt32((int)(at.Value.modified*256)); } client.send(charInfo); }