예제 #1
0
        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);
        }
예제 #2
0
        public void handlePartyInvite(MessageIn msg)
        {
            string inviterName = msg.readString();
            string inviteeName = msg.readString();
            ChatClient inviter = getClient(inviterName);
            ChatClient invitee = getClient(inviteeName);

            if (inviter==null|| invitee==null) return;

            removeExpiredPartyInvites();
            int maxInvitesPerTimeframe = 10;

            int num = mNumInvites[inviterName];

            if (num >= maxInvitesPerTimeframe)
            {
                MessageOut @out=new MessageOut(Protocol.CPMSG_PARTY_REJECTED);
                @out.writeString(inviterName);
                @out.writeInt8((int)ErrorMessage.ERRMSG_LIMIT_REACHED);
                inviter.send(@out);
                return;
            }
            ++num;

            if (invitee.party!=null)
            {
                MessageOut @out=new MessageOut(Protocol.CPMSG_PARTY_REJECTED);
                @out.writeString(inviterName);
                @out.writeInt8((int)ErrorMessage.ERRMSG_FAILURE);
                inviter.send(@out);
                return;
            }

            mInvitations.Add(new PartyInvite(inviterName, inviteeName));

            MessageOut msgout=new MessageOut(Protocol.CPMSG_PARTY_INVITED);
            msgout.writeString(inviterName);
            invitee.send(msgout);
        }
예제 #3
0
        protected override void processMessage(MessageIn msg)
        {
            switch(msg.getId())
            {
                case Protocol.AGMSG_REGISTER_RESPONSE:
                    {
                        if(msg.readInt16()!=(short)DataVersion.DATA_VERSION_OK)
                        {
                            Logger.Write(LogLevel.Error, "Item database is outdated! Please update to prevent inconsistencies");
                            stop();   //Disconnect gracefully from account server.
                            //Stop gameserver to prevent inconsistencies.
                            System.Environment.Exit((int)ExitValue.EXIT_DB_EXCEPTION);
                        }
                        else
                        {
                            Logger.Write(LogLevel.Debug, "Local item database is in sync with account server.");
                        }

                        if(msg.readInt16()!=(short)Password.PASSWORD_OK)
                        {
                            Logger.Write(LogLevel.Error, "This game server sent a invalid password");
                            stop();
                            System.Environment.Exit((int)ExitValue.EXIT_BAD_CONFIG_PARAMETER);
                        }

                        //read world state variables
                        while(msg.getUnreadLength()>0)
                        {
                            string key=msg.readString();
                            string @value=msg.readString();

                            if(key!=""&&@value!="")
                            {
                                GameState.setVariableFromDbserver(key,  @value);
                            }
                        }

                    }
                    break;

                case Protocol.AGMSG_PLAYER_ENTER:
                    {
                        string token=msg.readString();
                        Character ptr=new Character(msg);
                        Program.gameHandler.addPendingCharacter(token, ptr);
                    }
                    break;

                case Protocol.AGMSG_ACTIVE_MAP:
                    {
                        int mapId=msg.readInt16();
                        if(MapManager.activateMap(mapId))
                        {
                            // Set map variables
                            MapComposite m=MapManager.getMap(mapId);
                            int mapVarsNumber=msg.readInt16();
                            for(int i = 0;i < mapVarsNumber;++i)
                            {
                                string key=msg.readString();
                                string @value=msg.readString();
                                if(key!=""&&@value!="")
                                {
                                    m.setVariableFromDbserver(key,  @value);
                                }
                            }

                            //Recreate potential persistent floor items
                            Logger.Write(LogLevel.Debug, "Recreate persistant items on map {0}", mapId);
                            int floorItemsNumber=msg.readInt16();

                            for(int i = 0;i < floorItemsNumber;i += 4)
                            {
                                int itemId=msg.readInt32();
                                int amount=msg.readInt16();
                                int posX=msg.readInt16();
                                int posY=msg.readInt16();

                                ItemClass ic=Program.itemManager.getItem(itemId);

                                if(ic!=null)
                                {
                                    Item item=new Item(ic, amount);
                                    item.setMap(m);
                                    Point dst=new Point(posX, posY);
                                    item.setPosition(dst);

                                    if(!GameState.insertOrDelete((Thing)item))
                                    {
                                        // The map is full.
                                        Logger.Write(LogLevel.Debug, "Couldn't add floor item(s) {0}  into map {1}", itemId, mapId);
                                        return;
                                    }
                                }
                            }
                        }

                        break;
                    }
                case Protocol.AGMSG_SET_VAR_WORLD:
                    {
                        string key=msg.readString();
                        string @value=msg.readString();
                        GameState.setVariableFromDbserver(key, value);
                        Logger.Write(LogLevel.Debug, "Global variable \"{0}\" has changed to \"{1}\"", key,  @value);
                    }
                    break;

                case Protocol.AGMSG_REDIRECT_RESPONSE:
                    {
                        int id=msg.readInt32();
                        string token=msg.readString();
                        string address=msg.readString();
                        int port=msg.readInt16();
                        Program.gameHandler.completeServerChange(id, token, address, port);
                    }
                    break;

                case Protocol.AGMSG_GET_VAR_CHR_RESPONSE:
                    {
                        int id=msg.readInt32();
                        string name=msg.readString();
                        string @value=msg.readString();
                        Quest.recoveredQuestVar(id, name,  @value);
                    }
                    break;

                case Protocol.CGMSG_CHANGED_PARTY:
                    {
                        // Character DB id
                        int charid=msg.readInt32();
                        // Party id, 0 for none
                        int partyid=msg.readInt32();
                        Program.gameHandler.updateCharacter(charid, partyid);
                    }
                    break;

                case Protocol.CGMSG_POST_RESPONSE:
                    {
                        // get the character
                        Character character=Program.postMan.getCharacter(msg.readInt32());

                        // check character is still valid
                        if(character==null)
                        {
                            break;
                        }

                        string sender=msg.readString();
                        string letter=msg.readString();

                        Program.postMan.gotPost(character, sender, letter);

                    }
                    break;

                case Protocol.CGMSG_STORE_POST_RESPONSE:
                    {
                        // get character
                        Character character=Program.postMan.getCharacter(msg.readInt32());

                        // check character is valid
                        if(character==null)
                        {
                            break;
                        }

                        //TODO: Get NPC to tell character if the sending of post
                        //was successful or not

                    }
                    break;

                default:
                    {
                        Logger.Write(LogLevel.Warning, "Invalid message type");
                        break;
                    }
            }
        }
예제 #4
0
        void handleTopicChange(ChatClient client, MessageIn msg)
        {
            short channelId=msg.readInt16();
            string topic=msg.readString();
            ChatChannel channel=Program.chatChannelManager.getChannel(channelId);

            if(!Program.guildManager.doesExist(channel.getName()))
            {
                Program.chatChannelManager.setChannelTopic(channelId, topic);
            }
            else
            {
                guildChannelTopicChange(channel, (int)client.characterId, topic);
            }

            // log transaction
            Transaction trans=new Transaction();
            trans.mCharacterId=client.characterId;
            trans.mAction=(uint)TransactionMembers.TRANS_CHANNEL_TOPIC;
            trans.mMessage="User changed topic to "+topic;
            trans.mMessage+=(" in "+channel.getName());
            Program.storage.addTransaction(trans);
        }
예제 #5
0
        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);
        }
예제 #6
0
        bool mUpdateLevelProgress; /**< Flag raised when percent to next level changed */

        #endregion Fields

        #region Constructors

        public Character(MessageIn msg)
            : base(ThingType.OBJECT_CHARACTER)
        {
            //mTransactionHandler(NULL),
            mDatabaseID=-1;
            mLevel=1;
            mRecalculateLevel=true;
            mTransaction=TransactionType.TRANS_NONE;

            mExperience=new Dictionary<int, int>();

            Dictionary<int, List<AttributeInfoType>> attr=Program.attributeManager.getAttributeScope(ScopeType.CharacterScope);

            Logger.Write(LogLevel.Debug, "Character creation: initialisation of {0}  attributes.", attr.Count);
            foreach(KeyValuePair<int, List<AttributeInfoType>> pair in attr)
            {
                mAttributes.Add((uint)pair.Key, new Attribute(pair.Value));
            }

            // Get character data.
            mDatabaseID=msg.readInt32();
            setName(msg.readString());
            deserializeCharacterData(msg);
            mOld=getPosition();

            //TODO Ermitteln was hier eigentlich passieren sollte
            //Inventory(this).initialize();

            modifiedAllAttribute();
            setSize(16);

            // Give the character some specials for testing.
            //TODO: Get from quest vars and equipment
            giveSpecial(1);
            giveSpecial(2);
            giveSpecial(3);
        }
예제 #7
0
        void handleGuildCreate(ChatClient client, MessageIn msg)
        {
            MessageOut reply=new MessageOut(Protocol.CPMSG_GUILD_CREATE_RESPONSE);

            // Check if guild already exists and if so, return error
            string guildName = msg.readString();

            if (!Program.guildManager.doesExist(guildName))
            {
                // check the player hasnt already created a guild
                if(Program.guildManager.alreadyOwner((int)client.characterId))
                {
                    reply.writeInt8((int)ErrorMessage.ERRMSG_LIMIT_REACHED);
                }
                else
                {
                    // Guild doesnt already exist so create it
                    Guild guild=Program.guildManager.createGuild(guildName, (int)client.characterId);
                    reply.writeInt8((int)ErrorMessage.ERRMSG_OK);
                    reply.writeString(guildName);
                    reply.writeInt16(guild.getId());
                    reply.writeInt16(guild.getUserPermissions((int)client.characterId));

                    // Send autocreated channel id
                    ChatChannel channel = joinGuildChannel(guildName, client);
                    reply.writeInt16(channel.getId());
                }
            }
            else
            {
                reply.writeInt8((int)ErrorMessage.ERRMSG_ALREADY_TAKEN);
            }

            client.send(reply);
        }
예제 #8
0
        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);
        }
예제 #9
0
        void handleEnterChannelMessage(ChatClient client, MessageIn msg)
        {
            MessageOut reply=new MessageOut(Protocol.CPMSG_ENTER_CHANNEL_RESPONSE);

            string channelName=msg.readString();
            string givenPassword=msg.readString();
            ChatChannel channel=null;

            if(Program.chatChannelManager.channelExists(channelName)||
                Program.chatChannelManager.tryNewPublicChannel(channelName))
            {
                channel=Program.chatChannelManager.getChannel(channelName);
            }

            if(channel!=null)
            {
                reply.writeInt8((int)ErrorMessage.ERRMSG_INVALID_ARGUMENT);
            }
            else if(channel.getPassword()!=null&&channel.getPassword()!=givenPassword)
            {
                // Incorrect password (should probably have its own return value)
                reply.writeInt8((int)ErrorMessage.ERRMSG_INSUFFICIENT_RIGHTS);
            }
            else if(!channel.canJoin())
            {
                reply.writeInt8((int)ErrorMessage.ERRMSG_INVALID_ARGUMENT);
            }
            else
            {
                if(channel.addUser(client))
                {
                    reply.writeInt8((int)ErrorMessage.ERRMSG_OK);
                    // The user entered the channel, now give him the channel
                    // id, the announcement string and the user list.
                    reply.writeInt16(channel.getId());
                    reply.writeString(channelName);
                    reply.writeString(channel.getAnnouncement());
                    List<ChatClient> users=channel.getUserList();

                    foreach(ChatClient user in users)
                    {
                        reply.writeString(user.characterName);
                        reply.writeString(channel.getUserMode(user));
                    }

                    // Send an CPMSG_UPDATE_CHANNEL to warn other clients a user went
                    // in the channel.
                    warnUsersAboutPlayerEventInChat(channel, client.characterName, (int)ChatValues.CHAT_EVENT_NEW_PLAYER);

                    // log transaction
                    Transaction trans=new Transaction();
                    trans.mCharacterId=client.characterId;
                    trans.mAction=(uint)TransactionMembers.TRANS_CHANNEL_JOIN;
                    trans.mMessage="User joined "+channelName;
                    Program.storage.addTransaction(trans);
                }
                else
                {
                    reply.writeInt8((int)ErrorMessage.ERRMSG_FAILURE);
                }
            }

            client.send(reply);
        }
예제 #10
0
        void handleGuildAcceptInvite(ChatClient client, MessageIn msg)
        {
            MessageOut reply=new MessageOut(Protocol.CPMSG_GUILD_ACCEPT_RESPONSE);
            string guildName = msg.readString();
            bool error = true; // set true by default, and set false only if success

            // check guild exists and that member was invited
            // then add them as guild member
            // and remove from invite list
            Guild guild = Program.guildManager.findByName(guildName);

            if (guild!=null)
            {
                if (guild.checkInvited((int)client.characterId))
                {
                    // add user to guild
                    Program.guildManager.addGuildMember(guild, (int)client.characterId);
                    reply.writeInt8((int)ErrorMessage.ERRMSG_OK);
                    reply.writeString(guild.getName());
                    reply.writeInt16(guild.getId());
                    reply.writeInt16(guild.getUserPermissions((int)client.characterId));

                    // have character join guild channel
                    ChatChannel channel = joinGuildChannel(guild.getName(), client);
                    reply.writeInt16(channel.getId());
                    sendGuildListUpdate(guildName, client.characterName, (int)GuildValues.GUILD_EVENT_NEW_PLAYER);

                    // success! set error to false
                    error = false;
                }
            }

            if (error)
            {
                reply.writeInt8((int)ErrorMessage.ERRMSG_FAILURE);
            }

            client.send(reply);
        }
예제 #11
0
        void handleChatMessage(ChatClient client, MessageIn msg)
        {
            string text = msg.readString();

            // Pass it through the slang filter (false when it contains bad words)
            if (!Program.stringFilter.filterContent(text))
            {
                warnPlayerAboutBadWords(client);
                return;
            }

            short channelId = msg.readInt16();
            ChatChannel channel = Program.chatChannelManager.getChannel(channelId);

            if (channel!=null)
            {
            Logger.Write(LogLevel.Debug, "{0} says in channel {1}: {2}", client.characterName, channelId, text);

                MessageOut result=new MessageOut(Protocol.CPMSG_PUBMSG);
                result.writeInt16(channelId);
                result.writeString(client.characterName);
                result.writeString(text);
                sendInChannel(channel, result);
            }

            // log transaction
            Transaction trans=new Transaction();
            trans.mCharacterId = client.characterId;
            trans.mAction=(uint)TransactionMembers.TRANS_MSG_PUBLIC;
            trans.mMessage = "User said " + text;
            Program.storage.addTransaction(trans);
        }
예제 #12
0
        void handleAnnounceMessage(ChatClient client, MessageIn msg)
        {
            string text=msg.readString();

            if(!Program.stringFilter.filterContent(text))
            {
                warnPlayerAboutBadWords(client);
                return;
            }

            if(client.accountLevel==(byte)AccessLevel.AL_ADMIN||client.accountLevel==(byte)AccessLevel.AL_GM)
            {
                // TODO: b_lindeijer: Shouldn't announcements also have a sender?
                Logger.Write(LogLevel.Information, "ANNOUNCE: {0}", text);
                MessageOut result=new MessageOut(Protocol.CPMSG_ANNOUNCEMENT);
                result.writeString(text);

                // We send the message to all players in the default channel as it is
                // an announcement.
                sendToEveryone(result);

                // log transaction
                Transaction trans=new Transaction();
                trans.mCharacterId=client.characterId;
                trans.mAction=(uint)TransactionMembers.TRANS_MSG_ANNOUNCE;
                trans.mMessage="User announced "+text;
                Program.storage.addTransaction(trans);
            }
            else
            {
                MessageOut result=new MessageOut(Protocol.CPMSG_ERROR);
                result.writeInt8((int)ErrorMessage.ERRMSG_INSUFFICIENT_RIGHTS);
                client.send(result);
                Logger.Write(LogLevel.Information, "{0} couldn't make an announcement due to insufficient rights.", client.characterName);
            }
        }
예제 #13
0
        protected override void processMessage(NetComputer comp, MessageIn message)
        {
            ChatClient computer=(ChatClient)(comp);
            MessageOut result=new MessageOut();

            if(computer.characterName==null)
            {
                if(message.getId()!=Protocol.PCMSG_CONNECT) return;

                string magic_token=message.readString();
                mTokenCollector.addPendingClient(magic_token, computer);
                sendGuildRejoin(computer);
                return;
            }

            switch(message.getId())
            {
                case Protocol.PCMSG_CHAT:
                    handleChatMessage(computer, message);
                    break;

                case Protocol.PCMSG_ANNOUNCE:
                    handleAnnounceMessage(computer, message);
                    break;

                case Protocol.PCMSG_PRIVMSG:
                    handlePrivMsgMessage(computer, message);
                    break;

                case Protocol.PCMSG_WHO:
                    handleWhoMessage(computer);
                    break;

                case Protocol.PCMSG_ENTER_CHANNEL:
                    handleEnterChannelMessage(computer, message);
                    break;

                case Protocol.PCMSG_USER_MODE:
                    handleModeChangeMessage(computer, message);
                    break;

                case Protocol.PCMSG_KICK_USER:
                    handleKickUserMessage(computer, message);
                    break; //TODO hinzugef�gt, evt sollte es durchfallen

                case Protocol.PCMSG_QUIT_CHANNEL:
                    handleQuitChannelMessage(computer, message);
                    break;

                case Protocol.PCMSG_LIST_CHANNELS:
                    handleListChannelsMessage(computer, message);
                    break;

                case Protocol.PCMSG_LIST_CHANNELUSERS:
                    handleListChannelUsersMessage(computer, message);
                    break;

                case Protocol.PCMSG_TOPIC_CHANGE:
                    handleTopicChange(computer, message);
                    break;

                case Protocol.PCMSG_DISCONNECT:
                    handleDisconnectMessage(computer, message);
                    break;

                case Protocol.PCMSG_GUILD_CREATE:
                    handleGuildCreate(computer, message);
                    break;

                case Protocol.PCMSG_GUILD_INVITE:
                    handleGuildInvite(computer, message);
                    break;

                case Protocol.PCMSG_GUILD_ACCEPT:
                    handleGuildAcceptInvite(computer, message);
                    break;

                case Protocol.PCMSG_GUILD_GET_MEMBERS:
                    handleGuildGetMembers(computer, message);
                    break;

                case Protocol.PCMSG_GUILD_PROMOTE_MEMBER:
                    handleGuildMemberLevelChange(computer, message);
                    break;

                case Protocol.PCMSG_GUILD_KICK_MEMBER:
                    handleGuildKickMember(computer, message);
                    break; //TODO hinzugef�gt, evt sollte es durchfallen

                case Protocol.PCMSG_GUILD_QUIT:
                    handleGuildQuit(computer, message);
                    break;

                case Protocol.PCMSG_PARTY_INVITE_ANSWER:
                    handlePartyInviteAnswer(computer, message);
                    break;

                case Protocol.PCMSG_PARTY_QUIT:
                    handlePartyQuit(computer);
                    break;

                default:
                    Logger.Write(LogLevel.Warning, "processMessage, Invalid message type {0}", message.getId());
                    result.writeInt16((int)Protocol.XXMSG_INVALID);
                    break;
            }

            if(result.getLength()>0)
                computer.send(result);
        }
예제 #14
0
        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());
        }
예제 #15
0
        void handleGuildInvite(ChatClient client, MessageIn msg)
        {
            MessageOut reply=new MessageOut(Protocol.CPMSG_GUILD_INVITE_RESPONSE);
            MessageOut invite=new MessageOut(Protocol.CPMSG_GUILD_INVITED);

            // send an invitation from sender to character to join guild
            int guildId=msg.readInt16();
            string character=msg.readString();

            // get the chat client and the guild
            ChatClient invitedClient=mPlayerMap[character];
            Guild guild=Program.guildManager.findById((short)guildId);

            if(invitedClient!=null&&guild!=null)
            {
                // check permissions of inviter, and that they arent inviting themself,
                // and arent someone already in the guild
                if(guild.canInvite((int)client.characterId)&&(client.characterName!=character)&&!guild.checkInGuild((int)invitedClient.characterId))
                {
                    // send the name of the inviter and the name of the guild
                    // that the character has been invited to join
                    string senderName=client.characterName;
                    string guildName=guild.getName();
                    invite.writeString(senderName);
                    invite.writeString(guildName);
                    invite.writeInt16(guildId);
                    invitedClient.send(invite);
                    reply.writeInt8((int)ErrorMessage.ERRMSG_OK);

                    // add member to list of invited members to the guild
                    guild.addInvited((int)invitedClient.characterId);
                }
                else
                {
                    reply.writeInt8((int)ErrorMessage.ERRMSG_FAILURE);
                }
            }
            else
            {
                reply.writeInt8((int)ErrorMessage.ERRMSG_FAILURE);
            }

            client.send(reply);
        }
예제 #16
0
        void handlePrivMsgMessage(ChatClient client, MessageIn msg)
        {
            string user = msg.readString();
            string text = msg.readString();

            if (!Program.stringFilter.filterContent(text))
            {
                warnPlayerAboutBadWords(client);
                return;
            }

            // We seek the player to whom the message is told and send it to her/him.
            sayToPlayer(client, user, text);
        }
예제 #17
0
        void handleGuildKickMember(ChatClient client, MessageIn msg)
        {
            MessageOut reply=new MessageOut(Protocol.CPMSG_GUILD_KICK_MEMBER_RESPONSE);
            short guildId=msg.readInt16();
            string user=msg.readString();

            Guild guild=Program.guildManager.findById(guildId);
            Character c=Program.storage.getCharacter(user);

            if(guild!=null&&c!=null)
            {
                if((guild.getUserPermissions(c.getDatabaseID())&(int)(GuildAccessLevel.GAL_KICK))!=0) //TODO Überprüfen ob Vergleich so richtig rum
                {
                    reply.writeInt8((int)ErrorMessage.ERRMSG_OK);
                }
                else
                {
                    reply.writeInt8((int)ErrorMessage.ERRMSG_INSUFFICIENT_RIGHTS);
                }
            }
            else
            {
                reply.writeInt8((int)ErrorMessage.ERRMSG_INVALID_ARGUMENT);
            }

            client.send(reply);
        }
예제 #18
0
        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);
            }
        }
예제 #19
0
        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);
        }
예제 #20
0
        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);
        }
예제 #21
0
        void handleKickUserMessage(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 being kicked
            string user=msg.readString();

            if(channel.removeUser(getClient(user)))
            {
                string ss=client.characterName+":"+user;
                warnUsersAboutPlayerEventInChat(channel, ss, (int)ChatValues.CHAT_EVENT_KICKED_PLAYER);
            }

            // log transaction
            Transaction trans=new Transaction();
            trans.mCharacterId=client.characterId;
            trans.mAction=(uint)TransactionMembers.TRANS_CHANNEL_KICK;
            trans.mMessage="User kicked "+user;
            Program.storage.addTransaction(trans);
        }
예제 #22
0
        //    internal GameServer getGameServerFromMap(int);
        //internal void GameServerHandler::dumpStatistics(std::ostream &);
        /// <summary>
        /// Processes server messages.
        /// </summary>
        /// <param name="computer"></param>
        /// <param name="message"></param>
        protected override void processMessage(NetComputer computer, MessageIn message)
        {
            MessageOut result=new MessageOut();
            GameServer server=(GameServer)(computer);

            switch(message.getId())
            {
                case Protocol.GAMSG_REGISTER:
                    {
                        Logger.Write(LogLevel.Debug, "GAMSG_REGISTER");

                        // TODO: check the credentials of the game server
                        server.address=message.readString();
                        server.port=message.readInt16();
                        string password=message.readString();

                        // checks the version of the remote item database with our local copy
                        uint dbversion=(uint)message.readInt32();
                        Logger.Write(LogLevel.Information, "Game server uses itemsdatabase with version {0}", dbversion);

                        Logger.Write(LogLevel.Debug, "AGMSG_REGISTER_RESPONSE");
                        MessageOut outmessage=new MessageOut(Protocol.AGMSG_REGISTER_RESPONSE);

                        if(dbversion==Program.storage.getItemDatabaseVersion())
                        {
                            Logger.Write(LogLevel.Debug, "Item databases between account server and gameserver are in sync");
                            outmessage.writeInt16((int)DataVersion.DATA_VERSION_OK);
                        }
                        else
                        {
                            Logger.Write(LogLevel.Debug, "Item database of game server has a wrong version");
                            outmessage.writeInt16((int)DataVersion.DATA_VERSION_OUTDATED);
                        }
                        if(password==Configuration.getValue("net_password", "changeMe"))
                        {
                            outmessage.writeInt16((int)Password.PASSWORD_OK);
                            computer.send(outmessage);

                            // transmit global world state variables
                            Dictionary<string, string> variables;
                            variables=Program.storage.getAllWorldStateVars(0);

                            foreach(KeyValuePair<string, string> pair in variables)
                            {
                                outmessage.writeString(pair.Key);
                                outmessage.writeString(pair.Value);
                            }
                        }
                        else
                        {
                            Logger.Write(LogLevel.Information, "The password given by {0}:{1} was bad.", server.address, server.port);
                            outmessage.writeInt16((int)Password.PASSWORD_BAD);
                            computer.disconnect(outmessage);
                            break;
                        }

                        Logger.Write(LogLevel.Information, "Game server {0}:{1} wants to register {2}  maps.", server.address, server.port, (message.getUnreadLength()/2));

                        while(message.getUnreadLength()!=0)
                        {
                            int id=message.readInt16();
                            Logger.Write(LogLevel.Information, "Registering map {0}.", id);

                            GameServer s=GameServerHandler.getGameServerFromMap(id);
                            if(s!=null)
                            {
                                Logger.Write(LogLevel.Error, "Server Handler: map is already registered by {0}:{1}.", s.address, s.port);
                            }
                            else
                            {
                                MessageOut tmpOutMsg=new MessageOut(Protocol.AGMSG_ACTIVE_MAP);

                                // Map variables
                                tmpOutMsg.writeInt16(id);
                                Dictionary<string, string> variables;
                                variables=Program.storage.getAllWorldStateVars(id);

                                // Map vars number
                                tmpOutMsg.writeInt16(variables.Count);

                                foreach(KeyValuePair<string, string> pair in variables)
                                {
                                    tmpOutMsg.writeString(pair.Key);
                                    tmpOutMsg.writeString(pair.Value);
                                }

                                // Persistent Floor Items
                                List<FloorItem> items=Program.storage.getFloorItemsFromMap(id);

                                tmpOutMsg.writeInt16(items.Count); //number of floor items

                                // Send each map item: item_id, amount, pos_x, pos_y
                                foreach(FloorItem i in items)
                                {
                                    tmpOutMsg.writeInt32(i.getItemId());
                                    tmpOutMsg.writeInt16(i.getItemAmount());
                                    tmpOutMsg.writeInt16(i.getPosX());
                                    tmpOutMsg.writeInt16(i.getPosY());
                                }

                                computer.send(tmpOutMsg);
                                //MapStatistics m=server.maps[(ushort)id]; //Auskommentiert da nicht klar ist wo dieser Wert gesetzt wird
                                //m.nbThings=0;
                                //m.nbMonsters=0;
                            }
                        }
                    } break;

                case Protocol.GAMSG_PLAYER_DATA:
                    {
                        Logger.Write(LogLevel.Debug, "GAMSG_PLAYER_DATA");
                        int id=message.readInt32();

                        try
                        {
                            Character ptr=Program.storage.getCharacter(id, null);

                            CharacterData.deserializeCharacterData(ptr, message);
                            if(!Program.storage.updateCharacter(ptr))
                            {
                                Logger.Write(LogLevel.Error, "Failed to update character {0}.", id);
                            }
                        }
                        catch
                        {
                            Logger.Write(LogLevel.Error, "Received data for non-existing character {0}.", id);
                        }
                    } break;

                case Protocol.GAMSG_PLAYER_SYNC:
                    {
                        Logger.Write(LogLevel.Debug, "GAMSG_PLAYER_SYNC");
                        GameServerHandler.syncDatabase(message);
                    } break;

                case Protocol.GAMSG_REDIRECT:
                    {
                        Logger.Write(LogLevel.Debug, "GAMSG_REDIRECT");
                        int id=message.readInt32();
                        //string magic_token(utils::getMagicToken());
                        string magic_token=Various.GetUniqueID();

                        try
                        {
                            Character ptr=Program.storage.getCharacter(id, null);

                            int mapId=ptr.getMapId();

                            try
                            {
                                GameServer s=GameServerHandler.getGameServerFromMap(mapId);

                                GameServerHandler.registerGameClient(s, magic_token, ptr);
                                result.writeInt16((int)Protocol.AGMSG_REDIRECT_RESPONSE);
                                result.writeInt32(id);
                                result.writeString(magic_token);
                                result.writeString(s.address);
                                result.writeInt16(s.port);
                            }
                            catch
                            {
                                Logger.Write(LogLevel.Error, "Server Change: No game server for map {0}.", mapId);
                            }
                        }
                        catch
                        {
                            Logger.Write(LogLevel.Error, "Received data for non-existing character {0}.", id);
                        }
                    } break;

                case Protocol.GAMSG_PLAYER_RECONNECT:
                    {
                        Logger.Write(LogLevel.Debug, "GAMSG_PLAYER_RECONNECT");
                        int id=message.readInt32();
                        string magic_token=message.readString();
                        //string magic_token=message.readString(ManaServ.MAGIC_TOKEN_LENGTH);

                        try
                        {
                            Character ptr=Program.storage.getCharacter(id, null);
                            int accountID=ptr.getAccountID();
                            AccountClientHandler.prepareReconnect(magic_token, accountID);
                        }
                        catch
                        {
                            Logger.Write(LogLevel.Error, "Received data for non-existing character {0}.", id);
                        }
                    } break;

                case Protocol.GAMSG_GET_VAR_CHR:
                    {
                        int id=message.readInt32();
                        string name=message.readString();
                        string value=Program.storage.getQuestVar(id, name);
                        result.writeInt16((Int16)Protocol.AGMSG_GET_VAR_CHR_RESPONSE);
                        result.writeInt32(id);
                        result.writeString(name);
                        result.writeString(value);
                    } break;

                case Protocol.GAMSG_SET_VAR_CHR:
                    {
                        int id=message.readInt32();
                        string name=message.readString();
                        string value=message.readString();
                        Program.storage.setQuestVar(id, name, value);
                    } break;

                case Protocol.GAMSG_SET_VAR_WORLD:
                    {
                        string name=message.readString();
                        string value=message.readString();
                        // save the new value to the database
                        Program.storage.setWorldStateVar(name, value);

                        // relay the new value to all gameservers
                        foreach(NetComputer client in clients)
                        {
                            MessageOut varUpdateMessage=new MessageOut(Protocol.AGMSG_SET_VAR_WORLD);
                            varUpdateMessage.writeString(name);
                            varUpdateMessage.writeString(value);
                            client.send(varUpdateMessage);
                        }
                    } break;

                case Protocol.GAMSG_SET_VAR_MAP:
                    {
                        int mapid=message.readInt32();
                        string name=message.readString();
                        string value=message.readString();
                        Program.storage.setWorldStateVar(name, mapid, value);
                    } break;

                case Protocol.GAMSG_BAN_PLAYER:
                    {
                        int id=message.readInt32();
                        int duration=message.readInt32();
                        Program.storage.banCharacter(id, duration);
                    } break;

                case Protocol.GAMSG_CHANGE_PLAYER_LEVEL:
                    {
                        int id=message.readInt32();
                        int level=message.readInt16();
                        Program.storage.setPlayerLevel(id, level);
                    } break;

                case Protocol.GAMSG_CHANGE_ACCOUNT_LEVEL:
                    {
                        int id=message.readInt32();
                        int level=message.readInt16();

                        // get the character so we can get the account id
                        Character c=Program.storage.getCharacter(id, null);

                        if(c!=null)
                        {
                            Program.storage.setAccountLevel(c.getAccountID(), level);
                        }
                    } break;

                case Protocol.GAMSG_STATISTICS:
                    {
                        //while (message.getUnreadLength()!=0)
                        //{
                        //    int mapId = message.readInt16();
                        //    ServerStatistics::iterator i = server.maps.find(mapId);

                        //    if (i == server.maps.end())
                        //    {
                        //        Logger.Add(LogLevel.Error, "Server {0}:{1} should not be sending statistics for map {2}.", server.address, server.port, mapId);
                        //        // Skip remaining data.
                        //        break;
                        //    }

                        //    MapStatistics m = i.second;
                        //    m.nbThings =(ushort) message.readInt16();
                        //    m.nbMonsters=(ushort)message.readInt16();
                        //    int nb = message.readInt16();
                        //    m.players.resize(nb);
                        //    for (int j = 0; j < nb; ++j)
                        //    {
                        //        m.players[j] = message.readInt32();
                        //    }
                        //}
                    } break;

                case Protocol.GCMSG_REQUEST_POST:
                    {
                        // Retrieve the post for user
                        Logger.Write(LogLevel.Debug, "GCMSG_REQUEST_POST");
                        result.writeInt16((int)Protocol.CGMSG_POST_RESPONSE);

                        // get the character id
                        int characterId=message.readInt32();

                        // send the character id of sender
                        result.writeInt32(characterId);

                        // get the character based on the id
                        Character ptr=Program.storage.getCharacter(characterId, null);
                        if(ptr!=null)
                        {
                            // Invalid character
                            Logger.Write(LogLevel.Error, "Error finding character id for post");
                            break;
                        }

                        // get the post for that character
                        Post post=Program.postalManager.getPost(ptr);

                        // send the post if valid
                        if(post!=null)
                        {
                            for(int i=0; i<post.getNumberOfLetters(); ++i)
                            {
                                // get each letter, send the sender's name,
                                // the contents and any attachments
                                Letter letter=post.getLetter(i);
                                result.writeString(letter.getSender().getName());
                                result.writeString(letter.getContents());
                                List<InventoryItem> items=letter.getAttachments();

                                for(uint j=0; j<items.Count; ++j)
                                {
                                    result.writeInt16((int)items[(int)j].itemId);
                                    result.writeInt16((int)items[(int)j].amount);
                                }
                            }

                            // clean up
                            Program.postalManager.clearPost(ptr);
                        }

                    } break;

                case Protocol.GCMSG_STORE_POST:
                    {
                        //// Store the letter for the user
                        //Logger.Add(LogLevel.Debug, "GCMSG_STORE_POST");
                        //result.writeInt16((int)Protocol.CGMSG_STORE_POST_RESPONSE);

                        //// get the sender and receiver
                        //int senderId = message.readInt32();
                        //string receiverName = message.readString();

                        //// for sending it back
                        //result.writeInt32(senderId);

                        //// get their characters
                        //Character sender = Program.storage.getCharacter(senderId, null);
                        //Character receiver=Program.storage.getCharacter(receiverName);

                        //if (sender!=null || receiver!=null)
                        //{
                        //    // Invalid character
                        //    Logger.Add(LogLevel.Error, "Error finding character id for post");
                        //    result.writeInt8(ManaServ.ERRMSG_INVALID_ARGUMENT);
                        //    break;
                        //}

                        //// get the letter contents
                        //string contents = message.readString();

                        //List<Pair<int>> items;

                        //while (message.getUnreadLength()!=0)
                        //{
                        //    items.Add(new Pair<int>(message.readInt16(), message.readInt16()));
                        //}

                        //// save the letter
                        //Logger.Add(LogLevel.Debug, "Creating letter");
                        //Letter letter = new Letter(0, sender, receiver);
                        //letter.addText(contents);

                        //for (uint i = 0; i < items.Count; ++i)
                        //{
                        //    InventoryItem item;
                        //    item.itemId = items[i].first;
                        //    item.amount = items[i].second;
                        //    letter.addAttachment(item);
                        //}

                        //Program.postalManager.addLetter(letter);

                        //result.writeInt8(ManaServ.ERRMSG_OK);
                    } break;

                case Protocol.GAMSG_TRANSACTION:
                    {
                        Logger.Write(LogLevel.Debug, "TRANSACTION");
                        int id=message.readInt32();
                        int action=message.readInt32();
                        string messageS=message.readString();

                        Transaction trans=new Transaction();
                        trans.mCharacterId=(uint)id;
                        trans.mAction=(uint)action;
                        trans.mMessage=messageS;
                        Program.storage.addTransaction(trans);
                    } break;

                case Protocol.GCMSG_PARTY_INVITE:
                    Program.chatHandler.handlePartyInvite(message);
                    break;

                case Protocol.GAMSG_CREATE_ITEM_ON_MAP:
                    {
                        int mapId=message.readInt32();
                        int itemId=message.readInt32();
                        int amount=message.readInt16();
                        int posX=message.readInt16();
                        int posY=message.readInt16();

                        Logger.Write(LogLevel.Debug, "Gameserver create item {0} on map {1} ", itemId, mapId);

                        Program.storage.addFloorItem(mapId, itemId, amount, posX, posY);
                    } break;

                case Protocol.GAMSG_REMOVE_ITEM_ON_MAP:
                    {
                        int mapId=message.readInt32();
                        int itemId=message.readInt32();
                        int amount=message.readInt16();
                        int posX=message.readInt16();
                        int posY=message.readInt16();

                        Logger.Write(LogLevel.Debug, "Gameserver removed item {0} from map {1}", itemId, mapId);

                        Program.storage.removeFloorItem(mapId, itemId, amount, posX, posY);
                    } break;

                default:
                    {
                        Logger.Write(LogLevel.Warning, "ServerHandler::processMessage, Invalid message type: {0}", message.getId());
                        result.writeInt16((int)Protocol.XXMSG_INVALID);
                        break;
                    }
            }

            // return result
            if(result.getLength()>0)
            {
                computer.send(result);
            }
        }
예제 #23
0
        void handleListChannelUsersMessage(ChatClient client, MessageIn msg)
        {
            MessageOut reply=new MessageOut(Protocol.CPMSG_LIST_CHANNELUSERS_RESPONSE);

            string channelName=msg.readString();
            ChatChannel channel=Program.chatChannelManager.getChannel(channelName);

            if(channel!=null)
            {
                reply.writeString(channel.getName());

                List<ChatClient> users=channel.getUserList();

                foreach(ChatClient user in users)
                {
                    reply.writeString(user.characterName);
                    reply.writeString(channel.getUserMode(user));
                }

                client.send(reply);
            }

            // log transaction
            Transaction trans=new Transaction();
            trans.mCharacterId=client.characterId;
            trans.mAction=(uint)TransactionMembers.TRANS_CHANNEL_USERLIST;
            Program.storage.addTransaction(trans);
        }
예제 #24
0
        void sendPost(Character c, MessageIn msg)
        {
            // send message to account server with id of sending player,
            // the id of receiving player, the letter receiver and contents, and attachments
            Logger.Write(LogLevel.Debug, "Sending GCMSG_STORE_POST.");
            MessageOut outmsg=new MessageOut(Protocol.GCMSG_STORE_POST);
            outmsg.writeInt32(c.getDatabaseID());
            outmsg.writeString(msg.readString()); // name of receiver
            outmsg.writeString(msg.readString()); // content of letter

            while(msg.getUnreadLength()>0) // attachments
            {
                // write the item id and amount for each attachment
                outmsg.writeInt32(msg.readInt16());
                outmsg.writeInt32(msg.readInt16());
            }

            send(outmsg);
        }
예제 #25
0
        protected override void processMessage(NetComputer computer, MessageIn message)
        {
            GameClient client=(GameClient)computer;

            if(client.status==(int)AccountClientStatus.CLIENT_LOGIN)
            {
                if(message.getId()!=Protocol.PGMSG_CONNECT)
                    return;

                string magic_token=message.readString();
                client.status=(int)AccountClientStatus.CLIENT_QUEUED; // Before the addPendingClient
                mTokenCollector.addPendingClient(magic_token, client);
                return;
            }
            else if(client.status!=(int)AccountClientStatus.CLIENT_CONNECTED)
            {
                return;
            }

            switch(message.getId())
            {
                case Protocol.PGMSG_SAY:
                    {
                        handleSay(client, message);
                        break;
                    }
                case Protocol.PGMSG_NPC_TALK:
                case Protocol.PGMSG_NPC_TALK_NEXT:
                case Protocol.PGMSG_NPC_SELECT:
                case Protocol.PGMSG_NPC_NUMBER:
                case Protocol.PGMSG_NPC_STRING:
                    {
                        handleNpc(client, message);
                        break;
                    }
                case Protocol.PGMSG_PICKUP:
                    {
                        handlePickup(client, message);
                        break;
                    }
                case Protocol.PGMSG_USE_ITEM:
                    {
                        handleUseItem(client, message);
                        break;
                    }
                case Protocol.PGMSG_DROP:
                    {
                        handleDrop(client, message);
                        break;
                    }
                case Protocol.PGMSG_WALK:
                    {
                        handleWalk(client, message);
                        break;
                    }
                case Protocol.PGMSG_EQUIP:
                    {
                        handleEquip(client, message);
                        break;
                    }
                case Protocol.PGMSG_UNEQUIP:
                    {
                        handleUnequip(client, message);
                        break;
                    }
                case Protocol.PGMSG_MOVE_ITEM:
                    {
                        handleMoveItem(client, message);
                        break;
                    }
                case Protocol.PGMSG_ATTACK:
                    {
                        handleAttack(client, message);
                        break;
                    }
                case Protocol.PGMSG_USE_SPECIAL:
                    {
                        handleUseSpecial(client, message);
                        break;
                    }
                case Protocol.PGMSG_ACTION_CHANGE:
                    {
                        handleActionChange(client, message);
                        break;
                    }
                case Protocol.PGMSG_DIRECTION_CHANGE:
                    {
                        handleDirectionChange(client, message);
                        break;
                    }
                case Protocol.PGMSG_DISCONNECT:
                    {
                        handleDisconnect(client, message);
                        break;
                    }
                case Protocol.PGMSG_TRADE_REQUEST:
                    {
                        handleTradeRequest(client, message);
                        break;
                    }
                case Protocol.PGMSG_TRADE_CANCEL:
                case Protocol.PGMSG_TRADE_AGREED:
                case Protocol.PGMSG_TRADE_CONFIRM:
                case Protocol.PGMSG_TRADE_ADD_ITEM:
                case Protocol.PGMSG_TRADE_SET_MONEY:
                    {
                        handleTrade(client, message);
                        break;
                    }
                case Protocol.PGMSG_NPC_BUYSELL:
                    {
                        handleNpcBuySell(client, message);
                        break;
                    }
                case Protocol.PGMSG_RAISE_ATTRIBUTE:
                    {
                        handleRaiseAttribute(client, message);
                        break;
                    }
                case Protocol.PGMSG_LOWER_ATTRIBUTE:
                    {
                        handleLowerAttribute(client, message);
                        break;
                    }
                case Protocol.PGMSG_RESPAWN:
                    {
                        // plausibility check is done by character class
                        client.character.respawn();
                        break;
                    }
                case Protocol.PGMSG_NPC_POST_SEND:
                    {
                        handleNpcPostSend(client, message);
                        break;
                    }
                case Protocol.PGMSG_PARTY_INVITE:
                    {
                        handlePartyInvite(client, message);
                        break;
                    }
                default:
                    {
                        Logger.Write(LogLevel.Warning, "Invalid message type");
                        client.send(new MessageOut(Protocol.XXMSG_INVALID));
                        break;
                    }
            }
        }