// /** Sets the value of a base attribute of the character. */ // void setAttribute(unsigned int id, double value) // { mAttributes[id].base = value; } // // void setModAttribute(unsigned int id, double value) // { mAttributes[id].modified = value; } public void deserializeCharacterData(MessageIn msg) { // general character properties setAccountLevel(msg.readInt8()); setGender((BeingGender)msg.readInt8()); setHairStyle(msg.readInt8()); setHairColor(msg.readInt8()); setLevel(msg.readInt16()); setCharacterPoints(msg.readInt16()); setCorrectionPoints(msg.readInt16()); // character attributes uint attrSize=(uint)msg.readInt16(); for(uint i = 0;i < attrSize;++i) { uint id=(uint)msg.readInt16(); double @base=msg.readDouble(), mod=msg.readDouble(); setAttribute(id, @base); setModAttribute(id, mod); } // character skills int skillSize=msg.readInt16(); for(int i = 0;i < skillSize;++i) { int skill=msg.readInt16(); int level=msg.readInt32(); setExperience(skill, level); } // status effects currently affecting the character int statusSize=msg.readInt16(); for(int i = 0;i < statusSize;i++) { int status=msg.readInt16(); int time=msg.readInt16(); applyStatusEffect(status, time); } // location setMapId(msg.readInt16()); Point temporaryPoint=new Point(); temporaryPoint.x=msg.readInt16(); temporaryPoint.y=msg.readInt16(); setPosition(temporaryPoint); // kill count int killSize=msg.readInt16(); for(int i = 0;i < killSize;i++) { int monsterId=msg.readInt16(); int kills=msg.readInt32(); setKillCount(monsterId, kills); } // character specials int specialSize=msg.readInt16(); clearSpecials(); for(int i = 0;i < specialSize;i++) { giveSpecial(msg.readInt32()); } Possessions poss=getPossessions(); Dictionary< uint, EquipmentItem > equipData=new Dictionary<uint, EquipmentItem>(); int equipSlotsSize=msg.readInt16(); uint eqSlot; EquipmentItem equipItem=new EquipmentItem(); for(int j = 0;j < equipSlotsSize;++j) { eqSlot=(uint)msg.readInt16(); equipItem.itemId=(uint)msg.readInt16(); equipItem.itemInstance=(uint)msg.readInt16(); equipData.Add(eqSlot, equipItem); } poss.setEquipment(equipData); // Loads inventory - must be last because size isn't transmitted Dictionary<uint, InventoryItem > inventoryData=new Dictionary<uint, InventoryItem>(); while(msg.getUnreadLength()>0) { InventoryItem i=new InventoryItem(); int slotId=msg.readInt16(); i.itemId=(uint)msg.readInt16(); i.amount=(uint)msg.readInt16(); inventoryData.Add((uint)slotId, i); } poss.setInventory(inventoryData); }
public static void syncDatabase(MessageIn msg) { // It is safe to perform the following updates in a transaction //dal::PerformTransaction transaction(storage.database()); while(msg.getUnreadLength()>0) { int msgType=msg.readInt8(); switch((Sync)msgType) { case Sync.SYNC_CHARACTER_POINTS: { Logger.Write(LogLevel.Debug, "received SYNC_CHARACTER_POINTS"); int charId=msg.readInt32(); int charPoints=msg.readInt32(); int corrPoints=msg.readInt32(); Program.storage.updateCharacterPoints(charId, charPoints, corrPoints); break; } case Sync.SYNC_CHARACTER_ATTRIBUTE: { Logger.Write(LogLevel.Debug, "received SYNC_CHARACTER_ATTRIBUTE"); int charId=msg.readInt32(); int attrId=msg.readInt32(); double @base=msg.readDouble(); double mod=msg.readDouble(); Program.storage.updateAttribute(charId, (uint)attrId, @base, mod); break; } case Sync.SYNC_CHARACTER_SKILL: { Logger.Write(LogLevel.Debug, "received SYNC_CHARACTER_SKILL"); int charId=msg.readInt32(); int skillId=msg.readInt8(); int skillValue=msg.readInt32(); Program.storage.updateExperience(charId, skillId, skillValue); break; } case Sync.SYNC_ONLINE_STATUS: { Logger.Write(LogLevel.Debug, "received SYNC_ONLINE_STATUS"); int charId=msg.readInt32(); bool online=(msg.readInt8()==1); Program.storage.setOnlineStatus(charId, online); break; } } } //transaction.commit(); }
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 handlePartyInviteAnswer(ChatClient client, MessageIn msg) { if(client.party==null) return; MessageOut outInvitee=new MessageOut(Protocol.CPMSG_PARTY_INVITE_ANSWER_RESPONSE); string inviter=msg.readString(); // check if the invite is still valid bool valid=false; removeExpiredPartyInvites(); int size=mInvitations.Count; for(int i=0; i<size; i++) { if(mInvitations[i].mInviter==inviter&&mInvitations[i].mInvitee==client.characterName) { valid=true; } } // the invitee did not accept the invitation //if (msg.readInt8();) //{ msg.readInt8(); if(!valid) return; // send rejection to inviter ChatClient inviterClient=getClient(inviter); if(inviterClient!=null) { MessageOut outmsg=new MessageOut(Protocol.CPMSG_PARTY_REJECTED); outmsg.writeString(inviter); outmsg.writeInt8((int)ErrorMessage.ERRMSG_OK); inviterClient.send(outmsg); } return; //} // if the invitation has expired, tell the inivtee about it if(!valid) { outInvitee.writeInt8((int)ErrorMessage.ERRMSG_TIME_OUT); client.send(outInvitee); return; } // check that the inviter is still in the game ChatClient c1=getClient(inviter); if(c1==null) { outInvitee.writeInt8((int)ErrorMessage.ERRMSG_FAILURE); client.send(outInvitee); return; } // if party doesnt exist, create it if(c1.party!=null) { c1.party=new Party(); //c1.party.addUser(inviter); c1.party.addUser("", inviter); //TODO Überprüfen // tell game server to update info updateInfo(c1, (int)c1.party.getId()); } outInvitee.writeInt8((int)ErrorMessage.ERRMSG_OK); List<string> users=c1.party.getUsers(); int usersSize=users.Count; for(int i=0; i<usersSize; i++) { outInvitee.writeString(users[i]); } client.send(outInvitee); // add invitee to the party c1.party.addUser(client.characterName, inviter); client.party=c1.party; // tell game server to update info updateInfo(client, (int)client.party.getId()); }
void handleModeChangeMessage(ChatClient client, MessageIn msg) { short channelId=msg.readInt16(); ChatChannel channel=Program.chatChannelManager.getChannel(channelId); if(channelId==0||channel!=null) { // invalid channel return; } if(channel.getUserMode(client).IndexOf('o')==-1) { // invalid permissions return; } // get the user whos mode has been changed string user=msg.readString(); // get the mode to change to byte mode=msg.readInt8(); channel.setUserMode(getClient(user), mode); // set the info to pass to all channel clients string info=client.characterName+":"+user+":"+mode; warnUsersAboutPlayerEventInChat(channel, info, (int)ChatValues.CHAT_EVENT_MODE_CHANGE); // log transaction Transaction trans=new Transaction(); trans.mCharacterId=client.characterId; trans.mAction=(uint)TransactionMembers.TRANS_CHANNEL_MODE; trans.mMessage="User mode "; trans.mMessage+=mode+" set on "+user; Program.storage.addTransaction(trans); }
void handleGuildMemberLevelChange(ChatClient client, MessageIn msg) { // get the guild, the user to change the permissions, and the new permission // check theyre valid, and then change them MessageOut reply=new MessageOut(Protocol.CPMSG_GUILD_PROMOTE_MEMBER_RESPONSE); short guildId = msg.readInt16(); string user = msg.readString(); short level = msg.readInt8(); Guild guild = Program.guildManager.findById(guildId); Character c = Program.storage.getCharacter(user); if (guild!=null && c!=null) { int rights = guild.getUserPermissions(c.getDatabaseID()) | level; if(Program.guildManager.changeMemberLevel(client, guild, c.getDatabaseID(), rights)==0) { reply.writeInt8((int)ErrorMessage.ERRMSG_OK); client.send(reply); } } reply.writeInt8((int)ErrorMessage.ERRMSG_FAILURE); //TODO Muss das so oder fehlt oben ein return? client.send(reply); }