/// <summary>
        /// Handle a message from the messagebuffer
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnRecvReaderProcessMessage(object sender, MessageBufferEventArgs e)
        {
            if (e.Length > GameMessage.HEADERLENGTH)
            {
                // save encoded type
                byte encodedType = e.MessageBuffer[GameMessage.HEADERLENGTH];

                // decode type
                e.MessageBuffer[GameMessage.HEADERLENGTH] = PIDecoder.Decode(encodedType);

                try
                {
                    // mark as incoming message
                    e.Direction = MessageDirection.ServerToClient;

                    // parse the message to a typed instance
                    GameMessage typedMessage = ExtractMessage(e);
                    
                    // set encoded pi and memoryaddres
                    typedMessage.EncryptedPI = encodedType;
                    typedMessage.MemoryStartAddress = e.MemoryAddress;

                    // examine serversave value
                    CheckServerSave(typedMessage);

                    // trigger event for this new message
                    OnNewMessageAvailable(new GameMessageEventArgs(typedMessage));
                }
                catch (Exception Error)
                {
                    byte[] dump = new byte[e.Length];
                    Array.Copy(e.MessageBuffer, 0, dump, 0, e.Length);
                    OnHandlerError(new HandlerErrorEventArgs(dump, Error.Message));
                }
            }
            else
            {
                OnEmptyPacketFound(new EmptyMessageFoundEventArgs());
            }
        }
        /// <summary>
        /// Handle a message from the recv messagebuffer
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnSendReaderProcessMessage(object sender, MessageBufferEventArgs e)
        {
            if (e.Length > GameMessage.HEADERLENGTH)
            {
                try
                {
                    // set the direction as outgoing
                    e.Direction = MessageDirection.ClientToServer;

                    // parse the message
                    GameMessage typedMessage = ExtractMessage(e);
                    typedMessage.EncryptedPI = typedMessage.PI;
                    typedMessage.MemoryStartAddress = e.MemoryAddress;

                    CheckServerSave(typedMessage);

                    // Advance the hashtable if encryption is enabled (3. TX packet) and if it's not a blacklisted packet
                    if (CRCCreatorEnabled &&
                        advanceHashTable &&
                        ((MessageTypeGameMode)typedMessage.PI != MessageTypeGameMode.Blacklisted))

                        CRCCreator.AdvanceHashTable();

                    OnNewMessageAvailable(new GameMessageEventArgs(typedMessage));
                }
                catch (Exception Error)
                {
                    byte[] dump = new byte[e.Length];
                    Array.Copy(e.MessageBuffer, 0, dump, 0, e.Length);
                    OnHandlerError(new HandlerErrorEventArgs(dump, Error.Message));
                }
            }
            else
            {
                OnEmptyPacketFound(new EmptyMessageFoundEventArgs());
            }
        }
        /// <summary>
        /// Helper function for "ExtractMessage"
        /// </summary>
        /// <param name="e">MessageBuffer to extract from</param>
        /// <param name="PI">Message type</param>
        /// <returns>Typed message or generic instance of GameMessage</returns>
        protected unsafe GameMessage ExtractGameModeMessage(MessageBufferEventArgs e, MessageTypeGameMode PI)
        {
            GameMessage TypedMessage = null;

            // pin the byte[] for pointer parsers
            fixed (byte* pBuffer = e.MessageBuffer)
            {
                byte* pMessage = pBuffer;
                
                switch (PI)
                {
                    case MessageTypeGameMode.EchoPing:                                        // PI: 1
                        TypedMessage = new EchoPingMessage(e.MessageBuffer);
                        HandleEchoPing((EchoPingMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.Ping:                                            // PI: 3  
                        TypedMessage = new PingMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.System:                                          // PI: 6
                        TypedMessage = new SystemMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.Wait:                                            // PI: 21
                        TypedMessage = new WaitMessage(ref pMessage);
                        break;

                    case MessageTypeGameMode.Unwait:                                          // PI: 22
                        TypedMessage = new UnwaitMessage(ref pMessage);
                        break;

                    case MessageTypeGameMode.ChangePassword:                                  // PI: 23
                        TypedMessage = new ChangePasswordMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ChangeResource:                                  // PI: 30
                        TypedMessage = new ChangeResourceMessage(ref pMessage);
                        HandleChangeResource((ChangeResourceMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.SysMessage:                                      // PI: 31
                        TypedMessage = new SysMessageMessage(stringResources, e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.Message:                                         // PI: 32
                        TypedMessage = new MessageMessage(stringResources, ref pMessage);
                        break;

                    case MessageTypeGameMode.SendPlayer:                                      // PI: 40
                        TypedMessage = new SendPlayerMessage(ref pMessage);

                        break;
                    case MessageTypeGameMode.SendStats:                                       // PI: 41
                        TypedMessage = new SendStatsMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.SendRoomContents:                                // PI: 42
                        TypedMessage = new SendRoomContentsMessage(ref pMessage);
                        break;

                    case MessageTypeGameMode.SendObjectContents:                              // PI: 43
                        TypedMessage = new SendObjectContentsMessage(ref pMessage);
                        break;

                    case MessageTypeGameMode.SendPlayers:                                     // PI: 44
                        TypedMessage = new SendPlayersMessage(ref pMessage);
                        break;

                    case MessageTypeGameMode.SendCharacters:                                  // PI: 45           
                        TypedMessage = new SendCharactersMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.UseCharacter:                                    // PI: 46
                        TypedMessage = new UseCharacterMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.SendSpells:                                      // PI: 50
                        TypedMessage = new SendSpellsMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.SendSkills:                                      // PI: 51
                        TypedMessage = new SendSkillsMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.SendStatGroups:                                  // PI: 52
                        TypedMessage = new SendStatGroups(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.SendEnchantments:                                // PI: 53
                        TypedMessage = new SendEnchantmentsMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqQuit:                                         // PI: 54
                        TypedMessage = new ReqQuitMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.CharInfoOk:                                      // PI: 56
                        TypedMessage = new CharInfoOkMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.CharInfoNotOk:                                   // PI: 57
                        TypedMessage = new CharInfoNotOkMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.LoadModule:                                      // PI: 58
                        TypedMessage = new LoadModuleMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqAdmin:                                        // PI: 60
                        TypedMessage = new ReqAdminMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqDM:                                           // PI: 61
                        TypedMessage = new ReqDMMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.Effect:                                          // PI: 70
                        TypedMessage = new EffectMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.Mail:                                            // PI: 80
                        TypedMessage = new MailMessage(stringResources, e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqGetMail:                                      // PI: 81
                        TypedMessage = new ReqGetMailMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.SendMail:                                        // PI: 82
                        TypedMessage = new SendMailMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.DeleteMail:                                      // PI: 83
                        TypedMessage = new DeleteMailMessage(e.MessageBuffer);
                        break;
#if !VANILLA
                    case MessageTypeGameMode.DeleteNews:                                      // PI: 84
                        TypedMessage = new DeleteNewsMessage(e.MessageBuffer);
                        break;
#endif
                    case MessageTypeGameMode.ReqArticles:                                     // PI: 85
                        TypedMessage = new ReqArticlesMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqArticle:                                      // PI: 86
                        TypedMessage = new ReqArticleMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.PostArticle:                                     // PI: 87
                        TypedMessage = new PostArticleMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqLookupNames:                                  // PI: 88
                        TypedMessage = new ReqLookupNamesMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.Action:                                          // PI: 90
                        TypedMessage = new ActionMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqMove:                                         // PI: 100
                        TypedMessage = new ReqMoveMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqTurn:                                         // PI: 101
                        TypedMessage = new ReqTurnMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqGo:                                           // PI: 102
                        TypedMessage = new ReqGoMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqAttack:                                       // PI: 103
                        TypedMessage = new ReqAttackMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqCast:                                         // PI: 105
                        TypedMessage = new ReqCastMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqUse:                                          // PI: 106
                        TypedMessage = new ReqUseMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqUnuse:                                        // PI: 107
                        TypedMessage = new ReqUnuseMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqApply:                                        // PI: 108
                        TypedMessage = new ReqApplyMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqActivate:                                     // PI: 109
                        TypedMessage = new ReqActivateMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.SayTo:                                           // PI: 110
                        TypedMessage = new SayToMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.SayGroup:                                        // PI: 111
                        TypedMessage = new SayGroupMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqPut:                                          // PI: 112
                        TypedMessage = new ReqPutMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqGet:                                          // PI: 113
                        TypedMessage = new ReqGetMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqLook:                                         // PI: 116
                        TypedMessage = new ReqLookMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqInventory:                                    // PI: 117
                        TypedMessage = new ReqInventoryMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqDrop:                                         // PI: 118
                        TypedMessage = new ReqDropMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqOffer:                                        // PI: 120
                        TypedMessage = new ReqOfferMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.AcceptOffer:                                     // PI: 121
                        TypedMessage = new AcceptOfferMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.CancelOffer:                                     // PI: 122
                        TypedMessage = new CancelOfferMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqCounterOffer:                                 // PI: 123
                        TypedMessage = new CounterOfferMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqBuy:                                          // PI: 124
                        TypedMessage = new ReqBuyMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqBuyItems:                                     // PI: 125
                        TypedMessage = new ReqBuyItemsMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ChangeDescription:                               // PI: 126
                        TypedMessage = new ChangeDescriptionMessage(e.MessageBuffer);
                        break;
#if !VANILLA
                    case MessageTypeGameMode.ReqInventoryMove:                                // PI: 127
                        TypedMessage = new ReqInventoryMoveMessage(e.MessageBuffer);
                        break;
#endif
                    case MessageTypeGameMode.Player:                                          // PI: 130
                        TypedMessage = new PlayerMessage(ref pMessage);
                        HandlePlayer((PlayerMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.Stat:                                            // PI: 131
                        TypedMessage = new StatMessage(ref pMessage);
                        HandleStat((StatMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.StatGroup:                                       // PI: 132
                        TypedMessage = new StatGroupMessage(ref pMessage);
                        HandleStatGroup((StatGroupMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.StatGroups:                                      // PI: 133
                        TypedMessage = new StatGroupsMessage(ref pMessage);
                        HandleStatGroups((StatGroupsMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.RoomContents:                                    // PI: 134
                        TypedMessage = new RoomContentsMessage(ref pMessage);
                        HandleRoomContents((RoomContentsMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.ObjectContents:                                  // PI: 135
                        TypedMessage = new ObjectContentsMessage(ref pMessage);
                        HandleObjectContents((ObjectContentsMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.Players:                                         // PI: 136
                        TypedMessage = new PlayersMessage(ref pMessage);
                        HandlePlayers((PlayersMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.PlayerAdd:                                       // PI: 137
                        TypedMessage = new PlayerAddMessage(ref pMessage);
                        HandlePlayerAdd((PlayerAddMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.PlayerRemove:                                    // PI: 138
                        TypedMessage = new PlayerRemoveMessage(e.MessageBuffer);
                        HandlePlayerRemove((PlayerRemoveMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.Characters:                                      // PI: 139
                        TypedMessage = new CharactersMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.CharInfo:                                        // PI: 140
                        TypedMessage = new CharInfoMessage(e.MessageBuffer);
                        HandleCharInfo((CharInfoMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.Spells:                                          // PI: 141
                        TypedMessage = new SpellsMessage(ref pMessage);
                        HandleSpells((SpellsMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.SpellAdd:                                        // PI: 142
                        TypedMessage = new SpellAddMessage(ref pMessage);
                        HandleSpellAdd((SpellAddMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.SpellRemove:                                     // PI: 143
                        TypedMessage = new SpellRemoveMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.Skills:                                          // PI: 144
                        TypedMessage = new SkillsMessage(ref pMessage);
                        break;

                    case MessageTypeGameMode.SkillAdd:                                        // PI: 145
                        TypedMessage = new SkillAddMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.SkillRemove:                                     // PI: 146
                        TypedMessage = new SkillRemoveMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.AddEnchantment:                                  // PI: 147
                        TypedMessage = new AddEnchantmentMessage(e.MessageBuffer);
                        HandleAddEnchantment((AddEnchantmentMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.RemoveEnchantment:                               // PI: 148
                        TypedMessage = new RemoveEnchantmentMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.Quit:                                            // PI: 149
                        TypedMessage = new QuitMessage(e.MessageBuffer);
                        HandleQuit((QuitMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.Background:                                      // PI: 150
                        TypedMessage = new BackgroundMessage(e.MessageBuffer);
                        HandleBackground((BackgroundMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.PlayerOverlay:                                   // PI: 151
                        TypedMessage = new PlayerOverlayMessage(e.MessageBuffer);
                        HandlePlayerOverlay((PlayerOverlayMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.AddBgOverlay:                                    // PI: 152
                        TypedMessage = new AddBgOverlayMessage(ref pMessage);
                        HandleAddBgOverlay((AddBgOverlayMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.ChangeBgOverlay:                                 // PI: 154
                        TypedMessage = new ChangeBgOverlayMessage(ref pMessage);
                        HandleChangeBgOverlay((ChangeBgOverlayMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.UserCommand:                                     // PI: 155
                        TypedMessage = new UserCommandMessage(stringResources, e.Direction, e.MessageBuffer);
                        HandleUserCommand((UserCommandMessage)TypedMessage);
                        break;
#if !VANILLA
                    case MessageTypeGameMode.ReqStatChange:                                   // PI: 156
                        TypedMessage = new ReqStatChangeMessage(e.MessageBuffer);                
                        break;

                    case MessageTypeGameMode.ChangedStats:                                    // PI: 157
                        TypedMessage = new ChangedStatsMessage(e.MessageBuffer);
                        break;
#endif
                    case MessageTypeGameMode.PasswordOK:
                        TypedMessage = new PasswordOKMessage(e.MessageBuffer);                // PI: 160
                        break;

                    case MessageTypeGameMode.PasswordNotOK:                                   // PI: 161
                        TypedMessage = new PasswordNotOKMessage(e.MessageBuffer);                
                        break;

                    case MessageTypeGameMode.Admin:                                           // PI: 162
                        TypedMessage = new AdminMessage(e.MessageBuffer);                     
                        break;

                    case MessageTypeGameMode.PlayWave:                                        // PI: 170
                        TypedMessage = new PlayWaveMessage(ref pMessage);
                        HandlePlayWave((PlayWaveMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.PlayMusic:                                       // PI: 171
                        TypedMessage = new PlayMusicMessage(e.MessageBuffer);
                        HandlePlayMusic((PlayMusicMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.PlayMidi:                                        // PI: 172
                        TypedMessage = new PlayMidiMessage(e.MessageBuffer);
                        HandlePlayMidi((PlayMidiMessage)TypedMessage);
                        break;
#if !VANILLA
                    case MessageTypeGameMode.StopWave:                                       // PI: 173
                        TypedMessage = new StopWaveMessage(e.MessageBuffer);
                        HandleStopWave((StopWaveMessage)TypedMessage);
                        break;
#endif
                    case MessageTypeGameMode.LookNewsGroup:                                   // PI: 180
                        TypedMessage = new LookNewsGroupMessage(e.MessageBuffer);
                        HandleLookNewsGroup((LookNewsGroupMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.Articles:                                        // PI: 181
                        TypedMessage = new ArticlesMessage(ref pMessage);
                        break;

                    case MessageTypeGameMode.Article:                                         // PI: 182
                        TypedMessage = new ArticleMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.LookupNames:                                     // PI: 190
                        TypedMessage = new LookupNamesMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.Move:                                            // PI: 200
                        TypedMessage = new MoveMessage(ref pMessage);
                        break;

                    case MessageTypeGameMode.Turn:                                            // PI: 201
                        TypedMessage = new TurnMessage(ref pMessage);
                        break;

                    case MessageTypeGameMode.Shoot:                                           // PI: 202
                        TypedMessage = new ShootMessage(e.MessageBuffer);
                        HandleShoot((ShootMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.Use:                                             // PI: 203
                        TypedMessage = new UseMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.Unuse:                                           // PI: 204
                        TypedMessage = new UnuseMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.UseList:                                         // PI: 205
                        TypedMessage = new UseListMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.Said:                                            // PI: 206
                        TypedMessage = new SaidMessage(stringResources, ref pMessage);
                        break;

                    case MessageTypeGameMode.Look:                                            // PI: 207
                        TypedMessage = new LookMessage(stringResources, e.MessageBuffer);
                        HandleLook((LookMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.Inventory:                                       // PI: 208
                        TypedMessage = new InventoryMessage(ref pMessage);
                        HandleInventory((InventoryMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.InventoryAdd:                                    // PI: 209
                        TypedMessage = new InventoryAddMessage(e.MessageBuffer);
                        HandleInventoryAdd((InventoryAddMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.InventoryRemove:                                 // PI: 210
                        TypedMessage = new InventoryRemoveMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.Offer:                                           // PI: 211
                        TypedMessage = new OfferMessage(e.MessageBuffer);
                        HandleOffer((OfferMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.OfferCanceled:                                   // PI: 212
                        TypedMessage = new OfferCanceledMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.Offered:                                         // PI: 213
                        TypedMessage = new OfferedMessage(e.MessageBuffer);
                        HandleOffered((OfferedMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.CounterOffer:                                    // PI: 214
                        TypedMessage = new CounterOfferMessage(e.MessageBuffer);
                        HandleCounterOffer((CounterOfferMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.CounterOffered:                                  // PI: 215
                        TypedMessage = new CounterOfferedMessage(e.MessageBuffer);
                        HandleCounterOffered((CounterOfferedMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.BuyList:                                         // PI: 216
                        TypedMessage = new BuyListMessage(e.MessageBuffer);
                        HandleBuyList((BuyListMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.Create:                                          // PI: 217
                        TypedMessage = new CreateMessage(ref pMessage);
                        HandleCreate((CreateMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.Remove:                                          // PI: 218
                        TypedMessage = new RemoveMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.Change:                                          // PI: 219
                        TypedMessage = new ChangeMessage(ref pMessage);
                        HandleChange((ChangeMessage)TypedMessage);
                        break;

                    case MessageTypeGameMode.LightAmbient:                                    // PI: 220
                        TypedMessage = new LightAmbientMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.LightPlayer:                                     // PI: 221
                        TypedMessage = new LightPlayerMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.LightShading:                                    // PI: 222
                        TypedMessage = new LightShadingMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.SectorMove:                                      // PI: 223
                        TypedMessage = new SectorMoveMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.SectorLight:                                     // PI: 224
                        TypedMessage = new SectorLightMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.WallAnimate:                                     // PI: 225
                        TypedMessage = new WallAnimateMessage(ref pMessage);
                        break;

                    case MessageTypeGameMode.ChangeTexture:                                   // PI: 227
                        TypedMessage = new ChangeTextureMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.InvalidateData:                                  // PI: 228
                        TypedMessage = new InvalidateDataMessage(ref pMessage);
                        break;

                    case MessageTypeGameMode.ReqDeposit:                                      // PI: 230
                        TypedMessage = new ReqDepositMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.WithDrawAlList:                                  // PI: 231
                        TypedMessage = new WithdrawAlListMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqWithdrawAl:                                   // PI: 232
                        TypedMessage = new ReqWithdrawAlMessage(e.MessageBuffer);
                        break;

                    case MessageTypeGameMode.ReqWithdrawAlItems:                              // PI: 233
                        TypedMessage = new ReqWithDrawAlItemsMessage(e.MessageBuffer);
                        break;

                    default:
                        TypedMessage = new GenericGameMessage(e.MessageBuffer);              // All unknown ones
                        break;
                }
            }

            return TypedMessage;
        }        
        /// <summary>
        /// Helper function for "ExtractMessage"
        /// </summary>
        /// <param name="e">LoginMode Buffer</param>
        /// <param name="PI">Decoded PI</param>
        /// <returns>Typed message or generic</returns>
        protected unsafe GameMessage ExtractLoginModeMessage(MessageBufferEventArgs e, MessageTypeLoginMode PI)
        {
            GameMessage TypedMessage = null;
           
            // pin the byte[] for pointer parsers
            fixed (byte* pBuffer = e.MessageBuffer)
            {
                byte* pMessage = pBuffer;

                switch (PI)
                {
                    case MessageTypeLoginMode.Login:                  // PI: 2
                        TypedMessage = new LoginMessage(e.MessageBuffer);
                        break;

                    case MessageTypeLoginMode.ReqGame:                // PI: 4
                        TypedMessage = new ReqGameStateMessage(e.MessageBuffer);
                        break;

                    case MessageTypeLoginMode.ReqAdmin:               // PI: 5
                        TypedMessage = new ReqAdminMessageLoginMode(e.MessageBuffer);
                        break;

                    case MessageTypeLoginMode.GetClient:              // PI: 7
                        TypedMessage = new GetClientMessage(e.MessageBuffer);
                        break;

                    case MessageTypeLoginMode.GetLogin:               // PI: 21
                        TypedMessage = new GetLoginMessage(e.MessageBuffer);
                        break;

                    case MessageTypeLoginMode.GetChoice:              // PI: 22
                        TypedMessage = new GetChoiceMessage(e.MessageBuffer);
                        HandleGetChoice((GetChoiceMessage)TypedMessage);
                        break;

                    case MessageTypeLoginMode.LoginOK:                // PI: 23
                        TypedMessage = new LoginOKMessage(e.MessageBuffer);
                        break;

                    case MessageTypeLoginMode.LoginFailed:            // PI: 24
                        TypedMessage = new LoginFailedMessage(e.MessageBuffer);
                        break;

                    case MessageTypeLoginMode.Game:                   // PI: 25
                        TypedMessage = new GameStateMessage(e.MessageBuffer);
                        HandleGameState((GameStateMessage)TypedMessage);
                        break;

                    case MessageTypeLoginMode.Admin:                  // PI: 26
                        TypedMessage = new AdminMessageLoginMode(e.MessageBuffer);
                        break;

                    case MessageTypeLoginMode.Credits:                // PI: 30
                        TypedMessage = new CreditsMessage(e.MessageBuffer);
                        break;

                    case MessageTypeLoginMode.Download:               // PI: 31
                        TypedMessage = new DownloadMessage(ref pMessage);
                        break;
                        
                    case MessageTypeLoginMode.Message:                // PI: 34
                        TypedMessage = new LoginModeMessageMessage(e.MessageBuffer);
                        break;

                    case MessageTypeLoginMode.NoCharacters:           // PI: 37
                        TypedMessage = new NoCharactersMessage(e.MessageBuffer);
                        break;

                    default:
                        TypedMessage = new GenericGameMessage(e.MessageBuffer);     // All unknown ones
                        break;
                }
            }

            return TypedMessage;
        }
        /// <summary>
        /// Extract Message from a MessageBuffer (eventargs)
        /// </summary>
        /// <param name="e">MessageBufferEvent</param>
        /// <returns>Typed message or generic</returns>
        protected GameMessage ExtractMessage(MessageBufferEventArgs e)
        {
            GameMessage TypedMessage = null;
            byte PI = e.MessageBuffer[GameMessage.HEADERLENGTH];

            // parse packet based on current protocol mode
            switch (Mode)
            {
                // protocol mode Login
                case ProtocolMode.Login:
                    TypedMessage = ExtractLoginModeMessage(e, (MessageTypeLoginMode)PI);
                    break;

                // protocol mode Game
                case ProtocolMode.Game:
                    TypedMessage = ExtractGameModeMessage(e, (MessageTypeGameMode)PI);
                    break;
            }

            if (TypedMessage != null)
                TypedMessage.TransferDirection = e.Direction;

            return TypedMessage;
        }
Example #6
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="e"></param>
 protected void OnProcessMessage(MessageBufferEventArgs e)
 {
     if (MessageAvailable != null)
         MessageAvailable(this, e);
 }