public static void HandleRequest(Request request)
        {
            switch (request.CommandID)
            {
                case 0x28:
                    LoginCommand.HandleRequest(request);
                    break;

                case 0x32:
                    SilentLoginCommand.HandleRequest(request);
                    break;

                case 0x6E:
                    LoginPersonaCommand.HandleRequest(request);
                    break;

                case 0x1D:
                    ListUserEntitlements2Command.HandleRequest(request);
                    break;

                default:
                    Log.Warn(string.Format("Unhandled request: {0} {1}", request.ComponentID, request.CommandID));
                    break;
            }
        }
        public static void HandleRequest(Request request)
        {
            var attr = (TdfMap)request.Data["ATTR"];
            var gameName = (TdfString)request.Data["GNAM"];
            var gameSettings = (TdfInteger)request.Data["GSET"];
            var playerCapacity = (TdfList)request.Data["PCAP"];
            var igno = (TdfInteger)request.Data["IGNO"];
            var pmax = (TdfInteger)request.Data["PMAX"];
            var nres = (TdfInteger)request.Data["NRES"];

            var notResetable = (TdfInteger)request.Data["NTOP"];
            var voip = (TdfInteger)request.Data["VOIP"];

            var presence = (TdfInteger)request.Data["PRES"];
            var qcap = (TdfInteger)request.Data["QCAP"];

            var game = new Game();

            game.ClientID = request.Client.ID;

            game.Name = gameName.Value;
            game.Attributes = attr.Map;
            game.Capacity = playerCapacity.List;

            game.Level = attr.Map["level"].ToString();
            game.GameType = attr.Map["levellocation"].ToString();

            game.MaxPlayers = (ushort)pmax.Value;
            game.NotResetable = (byte)nres.Value;
            game.QueueCapacity = (ushort)qcap.Value;
            game.PresenceMode = (PresenceMode)presence.Value;
            game.State = GameState.Initializing;

            game.NetworkTopology = (GameNetworkTopology)notResetable.Value;
            game.VoipTopology = (VoipTopology)voip.Value;

            game.Settings = gameSettings.Value;

            game.InternalIP = request.Client.InternalIP;
            game.InternalPort = request.Client.InternalPort;

            game.ExternalIP = request.Client.ExternalIP;
            game.ExternalPort = request.Client.ExternalPort;

            GameManager.Add(game);

            request.Client.GameID = game.ID;

            Log.Info($"Client {request.Client.ID} creating game {game.ID} ({game.Name})");

            var data = new List<Tdf>
            {
                new TdfInteger("GID", (ulong)game.ID)
            };

            request.Reply(0, data);

            GameStateChangeNotification.Notify(request.Client);
            GameSetupNotification.Notify(request.Client);
        }
        public static void HandleRequest(Request request)
        {
            Log.Info(string.Format("Client {0} logging in to persona {1}", request.Client.ID, request.Client.User.Name));

            var data = new List<Tdf>
            {
                new TdfInteger("BUID", request.Client.User.ID),
                new TdfInteger("FRST", 0),
                new TdfString("KEY", ""),
                new TdfInteger("LLOG", Utils.GetUnixTime()),
                new TdfString("MAIL", request.Client.User.Email),
                new TdfStruct("PDTL", new List<Tdf>
                {
                    new TdfString("DSNM", request.Client.User.Name),
                    new TdfInteger("LAST", Utils.GetUnixTime()),
                    new TdfInteger("PID", request.Client.User.ID),
                    new TdfInteger("STAS", 2),
                    new TdfInteger("XREF", 0),
                    new TdfInteger("XTYP", (ulong)ExternalRefType.Unknown)
                }),
                new TdfInteger("UID", (ulong)request.Client.ID)
            };

            request.Reply(0, data);

            UserAddedNotification.Notify(request.Client, request.Client.User.ID, request.Client.User.Name);
            UserUpdatedNotification.Notify(request.Client, request.Client.User.ID);
        }
        public static void HandleRequest(Request request)
        {
            var gameID = (TdfInteger)request.Data["GID"];

            Log.Info(string.Format("Client {0} updating game {1} session", request.Client.ID, gameID.Value));

            request.Reply();
        }
        public static void HandleRequest(Request request)
        {
            var data = new List<Tdf>
            {
                new TdfInteger("STIM", Utils.GetUnixTime())
            };

            request.Reply(0, data);
        }
        public static void HandleRequest(Request request)
        {
            Log.Info(string.Format("Client {0} requested stats group", request.Client.ID));

            var data = new List<Tdf>
            {
                
            };

            request.Reply(0, data);
        }
        public static void HandleRequest(Request request)
        {
            Log.Info(string.Format("Client {0} requested RSP configuration", request.Client.ID));

            foreach (var tdf in request.Data)
            {
                Log.Info(tdf.Key + "(" + tdf.Value.Type + ")");
            }

            request.Reply();
        }
        public static void HandleRequest(Request request)
        {
            var gameID = (TdfInteger)request.Data["GID"];

            /* if (!GameManager.Games.ContainsKey(gameID.Value))
            {
                request.Reply(0x12D0004, null);
                return;
            } */

            //request.Reply();
        }
        public static void HandleRequest(Request request)
        {
            switch (request.CommandID)
            {
                case 1:
                    CreateGameCommand.HandleRequest(request);
                    break;

                case 2:
                    Log.Warn("DESTROY GAME");
                    break;

                case 3:
                    AdvanceGameStateCommand.HandleRequest(request);
                    break;

                case 4:
                    SetGameSettingsCommand.HandleRequest(request);
                    break;

                case 5:
                    Log.Info("SET PLAYER CAPACITY");
                    //SetPlayerCapacityCommand.HandleRequest(request);
                    break;

                case 7:
                    Log.Info("SET GAME ATTRIBUTES");
                    //SetGameAttributesCommand.HandleRequest(request);
                    break;

                case 9:
                    JoinGameCommand.HandleRequest(request);
                    break;

                case 0xB:
                    Log.Warn("*GameManager->HandleRemovePlayerCommand*");
                    //HandleRemovePlayerCommand(clientId, request, stream);
                    break;

                case 0xF:
                    FinalizeGameCreationCommand.HandleRequest(request);
                    break;

                case 0x1D:
                    UpdateMeshConnectionCommand.HandleRequest(request);
                    break;

                default:
                    Log.Warn(string.Format("Unhandled request: {0} {1}", request.ComponentID, request.CommandID));
                    break;
            }
        }
        public static void HandleRequest(Request request)
        {
            switch (request.CommandID)
            {
                case 0xA8C:
                    GetClubMembershipForUsersCommand.HandleRequest(request);
                    break;

                default:
                    Log.Warn(string.Format("Unhandled request: {0} {1}", request.ComponentID, request.CommandID));
                    break;
            }
        }
        public static void HandleRequest(Request request)
        {
            var gameID = (TdfInteger)request.Data["GID"];
            var gameSettings = (TdfInteger)request.Data["GSET"];

            Log.Info(string.Format("Client {0} setting game settings to {1}", gameID.Value, gameSettings.Value));

            GameManager.Games[gameID.Value].Settings = gameSettings.Value;

            request.Reply();

            GameSettingsChangeNotification.Notify(request.Client);
        }
        public static void HandleRequest(Request request)
        {
            switch (request.CommandID)
            {
                case 0x14:
                    UpdateNetworkInfoCommand.HandleRequest(request);
                    break;

                default:
                    Log.Warn(string.Format("Unhandled request: {0} {1}", request.ComponentID, request.CommandID));
                    break;
            }
        }
        public static void HandleRequest(Request request)
        {
            switch (request.CommandID)
            {
                case 1:
                    GetServerInstanceCommand.HandleRequest(request);
                    break;

                default:
                    Log.Warn(string.Format("Unhandled request: {0} {1}", request.ComponentID, request.CommandID));
                    break;
            }
        }
        public static void HandleRequest(Request request)
        {
            var gameID = (TdfInteger)request.Data["GID"];
            var gameState = (TdfInteger)request.Data["GSTA"];

            Log.Info(string.Format("Client {0} changing game {1} state to {2}", request.Client.ID, gameID.Value, (GameState)gameState.Value));

            var game = GameManager.Games[gameID.Value];
            game.State = (GameState)gameState.Value;

            request.Reply();

            GameStateChangeNotification.Notify(request.Client);
        }
        public static void HandleRequest(Request request)
        {
            Log.Info(string.Format("Client {0} post-authenticating", request.Client.ID));

            var data = new List<Tdf>
            {
                new TdfStruct("PSS", new List<Tdf>
                {
                    new TdfString("ADRS", "127.0.0.1"),
                    new TdfBlob("CSIG", new byte[] { }),                   
                    new TdfString("PJID", "123071"),
                    new TdfInteger("PORT", 8443),
                    new TdfInteger("RPRT", 9),
                    new TdfInteger("TIID", 0)
                }),
                new TdfStruct("TELE", new List<Tdf>
                {
                    new TdfString("ADRS", "127.0.0.1"),
                    new TdfInteger("ANON", 0),

                    new TdfString("DISA", "AD,AF,AG,AI,AL,AM,AN,AO,AQ,AR,AS,AW,AX,AZ,BA,BB,BD,BF,BH,BI,BJ,BM,BN,BO,BR,BS,BT,BV,BW,BY,BZ,CC,CD,CF,CG,CI,CK,CL,CM,CN,CO,CR,CU,CV,CX,DJ,DM,DO,DZ,EC,EG,EH,ER,ET,FJ,FK,FM,FO,GA,GD,GE,GF,GG,GH,GI,GL,GM,GN,GP,GQ,GS,GT,GU,GW,GY,HM,HN,HT,ID,IL,IM,IN,IO,IQ,IR,IS,JE,JM,JO,KE,KG,KH,KI,KM,KN,KP,KR,KW,KY,KZ,LA,LB,LC,LI,LK,LR,LS,LY,MA,MC,MD,ME,MG,MH,ML,MM,MN,MO,MP,MQ,MR,MS,MU,MV,MW,MY,MZ,NA,NC,NE,NF,NG,NI,NP,NR,NU,OM,PA,PE,PF,PG,PH,PK,PM,PN,PS,PW,PY,QA,RE,RS,RW,SA,SB,SC,SD,SG,SH,SJ,SL,SM,SN,SO,SR,ST,SV,SY,SZ,TC,TD,TF,TG,TH,TJ,TK,TL,TM,TN,TO,TT,TV,TZ,UA,UG,UM,UY,UZ,VA,VC,VE,VG,VN,VU,WF,WS,YE,YT,ZM,ZW,ZZ"),
                    new TdfString("FILT", ""),
                    new TdfInteger("LOC", request.Client.Localization),

                    new TdfString("NOOK", "US,CA,MX"),
                    new TdfInteger("PORT", 9988),

                    new TdfInteger("SDLY", 15000),
                    new TdfString("SESS", "telemetry_session"),
                    new TdfString("SKEY", "telemetry_key"),
                    new TdfInteger("SPCT", 75),
                    new TdfString("STIM", "Default")
                }),
                new TdfStruct("TICK", new List<Tdf>
                {
                    new TdfString("ADRS", "127.0.0.1"),
                    new TdfInteger("PORT", 8999),
                    new TdfString("SKEY", string.Format("{0},127.0.0.1:8999,battlefield-3-pc,10,50,50,50,50,0,12", request.Client.User.ID))
                }),
                new TdfStruct("UROP", new List<Tdf>
                {
                    new TdfInteger("TMOP", (ulong)TelemetryOpt.OptIn),
                    new TdfInteger("UID", request.Client.User.ID)
                })
            };

            request.Reply(0, data);
        }
        public static void HandleRequest(Request request)
        {
            switch (request.CommandID)
            {
                case 0x64:
                    SubmitTrustedMidGameReportCommand.HandleRequest(request);
                    break;

                case 0x65:
                    SubmitTrustedEndGameReportCommand.HandleRequest(request);
                    break;

                default:
                    Log.Warn(string.Format("Unhandled request: {0} {1}", request.ComponentID, request.CommandID));
                    break;
            }
        }
        public static void HandleRequest(Request request)
        {
            Log.Info(string.Format("Client {0} saving user settings for user {1}", request.Client.ID, request.Client.User.ID));

            var data = (TdfString)request.Data["DATA"];

            Directory.CreateDirectory(string.Format(".\\data\\{0}", request.Client.User.ID));

            if (File.Exists(string.Format(".\\data\\{0}\\user_settings", request.Client.User.ID)))
            {
                File.Delete(string.Format(".\\data\\{0}\\user_settings", request.Client.User.ID));
            }

            File.WriteAllBytes(string.Format(".\\data\\{0}\\user_settings", request.Client.User.ID), Encoding.ASCII.GetBytes(data.Value));

            request.Reply();
        }
        public static void HandleRequest(Request request)
        {
            Log.Info(string.Format("Client {0} requested client configuration", request.Client.ID));

            var clientConfigID = (TdfString)request.Data["CFID"];

            var data = new List<Tdf>
            {
                new TdfMap("CONF", TdfBaseType.String, TdfBaseType.String, new Dictionary<object, object>
                {
                    { "Achievements", "ACH32_00,ACH33_00,ACH34_00,ACH35_00,ACH36_00,ACH37_00,ACH38_00,ACH39_00,ACH40_00,XPACH01_00,XPACH02_00,XPACH03_00,XPACH04_00,XPACH05_00,XP2ACH01_00,XP2ACH04_00,XP2ACH03_00,XP2ACH05_00,XP2ACH02_00,XP3ACH01_00,XP3ACH05_00,XP3ACH03_00,XP3ACH04_00,XP3ACH02_00,XP4ACH01_00,XP4ACH02_00,XP4ACH03_00,XP4ACH04_00,XP4ACH05_00,XP5ACH01_00,XP5ACH02_00,XP5ACH03_00,XP5ach04_00,XP5ach05_00" },
                    { "WinCodes", "r01_00,r05_00,r04_00,r03_00,r02_00,r10_00,r08_00,r07_00,r06_00,r09_00,r11_00,r12_00,r13_00,r14_00,r15_00,r16_00,r17_00,r18_00,r19_00,r20_00,r21_00,r22_00,r23_00,r24_00,r25_00,r26_00,r27_00,r28_00,r29_00,r30_00,r31_00,r32_00,r33_00,r35_00,r36_00,r37_00,r34_00,r38_00,r39_00,r40_00,r41_00,r42_00,r43_00,r44_00,r45_00,xp2rgm_00,xp2rntdmcq_00,xp2rtdmc_00,xp3rts_00,xp3rdom_00,xp3rnts_00,xp3rngm_00,xp4rndom_00,xp4rscav_00,xp4rnscv_00,xp4ramb1_00,xp4ramb2_00,xp5r502_00,xp5r501_00,xp5ras_00,xp5asw_00" }
                })
            };

            request.Reply(0, data);
        }
        public static void HandleRequest(Request request)
        {
            switch (request.CommandID)
            {
                case 4:
                    GetStatGroupCommand.HandleRequest(request);
                    break;

                case 0x10:
                    GetStatsByGroupAsyncCommand.HandleRequest(request);
                    break;

                default:
                    Log.Warn(string.Format("Unhandled request: {0} {1}", request.ComponentID, request.CommandID));
                    break;
            }
        }
        public static void HandleRequest(Request request)
        {
            Log.Info(string.Format("Client {0} updating mesh connection", request.Client.ID));

            var gameID = (TdfInteger)request.Data["GID"];

            var targ = (TdfList)request.Data["TARG"];
            var targData = (List<Tdf>)targ.List[0];
            var playerID = (TdfInteger)targData[1];
            var stat = (TdfInteger)targData[2];

            request.Reply();

            if (stat.Value == 2)
            {
                if (request.Client.Type == ClientType.GameplayUser)
                {
                    GamePlayerStateChangeNotification.Notify(request.Client, gameID.Value, request.Client.User.ID);
                    PlayerJoinCompletedNotification.Notify(request.Client, gameID.Value, request.Client.User.ID);
                }
                else if (request.Client.Type == ClientType.DedicatedServer)
                {
                    GamePlayerStateChangeNotification.Notify(request.Client, gameID.Value, playerID.Value);
                    PlayerJoinCompletedNotification.Notify(request.Client, gameID.Value, playerID.Value);
                }
            }
            else if (stat.Value == 0)
            {
                if (request.Client.Type == ClientType.GameplayUser)
                {
                    var game = GameManager.Games[gameID.Value];
                    game.Slots.Remove(playerID.Value);

                    PlayerRemovedNotification.Notify(request.Client, playerID.Value);
                }
                else if (request.Client.Type == ClientType.DedicatedServer)
                {
                    var game = GameManager.Games[gameID.Value];
                    game.Slots.Remove(playerID.Value);

                    PlayerRemovedNotification.Notify(request.Client, playerID.Value);
                }
            }
        }
        public static void HandleRequest(Request request)
        {
            var email = (TdfString)request.Data["MAIL"];

            Log.Info(string.Format("Client {0} logging in with email {1}", request.Client.ID, email.Value));

            var user = Configuration.Users.Find(u => u.Email == email.Value);

            if (user == null)
            {
                Log.Warn("User not found");
                return;
            }

            request.Client.User = user;

            var data = new List<Tdf>
            {
                new TdfString("LDHT", ""),
                new TdfInteger("NTOS", 0),
                new TdfString("PCTK", ""),
                new TdfList("PLST", TdfBaseType.Struct, new ArrayList
                {
                    new List<Tdf>
                    {
                        new TdfString("DSNM", user.Name),
                        new TdfInteger("LAST", 0),
                        new TdfInteger("PID", user.ID),
                        new TdfInteger("STAS", 2),
                        new TdfInteger("XREF", 0),
                        new TdfInteger("XTYP", (ulong)ExternalRefType.Unknown)
                    }
                }),
                new TdfString("PRIV", ""),
                new TdfString("SKEY", ""),
                new TdfInteger("SPAM", 1),
                new TdfString("THST", ""),
                new TdfString("TSUI", ""),
                new TdfString("TURI", ""),
                new TdfInteger("UID", (ulong)request.Client.ID)
            };

            request.Reply(0, data);
        }
        public static void HandleRequest(Request request)
        {
            Log.Info(string.Format("Client {0} updating network info", request.Client.ID));

            var addr = (TdfUnion)request.Data["ADDR"];
            var valu = (TdfStruct)addr.Data.Find(tdf => tdf.Label == "VALU");

            var inip = (TdfStruct)valu.Data.Find(tdf => tdf.Label == "INIP");
            var ip = (TdfInteger)inip.Data.Find(tdf => tdf.Label == "IP");
            var port = (TdfInteger)inip.Data.Find(tdf => tdf.Label == "PORT");

            request.Client.InternalIP = ip.Value;
            request.Client.InternalPort = (ushort)port.Value;

            request.Client.ExternalIP = ip.Value;
            request.Client.ExternalPort = (ushort)port.Value;

            request.Reply();
        }
        public static void HandleRequest(Request request)
        {
            Log.Info(string.Format("Client {0} requesting ServerInstanceInfo", request.Client.ID));

            request.Reply(0, new List<Tdf>
            {
                new TdfUnion("ADDR", NetworkAddressMember.XboxClientAddress, new List<Tdf>
                {
                    new TdfStruct("VALU", new List<Tdf>
                    {
                        new TdfString("HOST", "373244-gosprapp357.ea.com"),
                        new TdfInteger("IP", 0),
                        new TdfInteger("PORT", 10041)
                    })
                }),
                new TdfInteger("SECU", 1),
                new TdfInteger("XDNS", 0)
            });
        }
        public static void HandleRequest(Request request)
        {
            var personaID = (TdfInteger)request.Data["PID"];

            var user = Configuration.Users.Find(u => u.ID == personaID.Value);
            request.Client.User = user;

            var data = new List<Tdf>
            {
                new TdfInteger("AGUP", 0),
                new TdfString("LDHT", ""),
                new TdfInteger("NTOS", 0),
                new TdfString("PCTK", ""),
                new TdfString("PRIV", ""),
                new TdfStruct("SESS", new List<Tdf>
                {
                    new TdfInteger("BUID", request.Client.User.ID),
                    new TdfInteger("FRST", 0),
                    new TdfString("KEY", ""),
                    new TdfInteger("LLOG", 0),
                    new TdfString("MAIL", request.Client.User.Email),
                    new TdfStruct("PDTL", new List<Tdf>
                    {
                        new TdfString("DSNM", request.Client.User.Name),
                        new TdfInteger("LAST", 0),
                        new TdfInteger("PID", request.Client.User.ID),
                        new TdfInteger("STAS", 0),
                        new TdfInteger("XREF", 0),
                        new TdfInteger("XTYP", (ulong)ExternalRefType.Unknown)
                    }),
                    new TdfInteger("UID", (ulong)request.Client.ID)
                }),
                new TdfInteger("SPAM", 0),
                new TdfString("THST", ""),
                new TdfString("TSUI", ""),
                new TdfString("TURI", "")
            };

            request.Reply(0, data);

            UserAddedNotification.Notify(request.Client, request.Client.User.ID, request.Client.User.Name);
            UserUpdatedNotification.Notify(request.Client, request.Client.User.ID);
        }
        public static void HandleRequest(Request request)
        {
            switch (request.CommandID)
            {
                case 1:
                    FetchClientConfigCommand.HandleRequest(request);
                    break;

                case 2:
                    PingCommand.HandleRequest(request);
                    break;

                case 5:
                    GetTelemetryServerCommand.HandleRequest(request);
                    break;

                case 7:
                    PreAuthCommand.HandleRequest(request);
                    break;

                case 8:
                    PostAuthCommand.HandleRequest(request);
                    break;

                case 0xB:
                    UserSettingsSaveCommand.HandleRequest(request);
                    break;

                case 0xC:
                    UserSettingsLoadAllCommand.HandleRequest(request);
                    break;

                case 0x16:
                    SetClientMetricsCommand.HandleRequest(request);
                    break;

                default:
                    Log.Warn(string.Format("Unhandled request: {0} {1}", request.ComponentID, request.CommandID));
                    break;
            }
        }
        public static void HandleRequest(Request request)
        {
            Log.Info(string.Format("Client {0} loading all user settings for user {1}", request.Client.ID, request.Client.User.ID));

            if (File.Exists(string.Format(".\\data\\{0}\\user_settings", request.Client.User.ID)))
            {
                var userSettings = File.ReadAllBytes(string.Format(".\\data\\{0}\\user_settings", request.Client.User.ID));

                var data = new List<Tdf>
                {
                    new TdfMap("SMAP", TdfBaseType.String, TdfBaseType.String, new Dictionary<object, object>
                    {
                        { "cust", userSettings.ToString() }
                    })
                };

                request.Reply(0, data);
            }
            else
            {
                request.Reply();
            }
        }
        public static void HandleRequest(Request request)
        {
            var gameID = (TdfInteger)request.Data["GID"];

            if (!GameManager.Games.ContainsKey(gameID.Value))
            {
                request.Reply(0x12D0004, null);
                return;
            }

            request.Client.GameID = gameID.Value;

            var data = new List<Tdf>
            {
                new TdfInteger("GID", (ulong)gameID.Value),
                new TdfInteger("JGS", 0)
            };

            request.Reply(0, data);

            var game = GameManager.Games[gameID.Value];
            var gameClient = BlazeServer.Clients[game.ClientID];

            game.Slots.Add(request.Client.User.ID);
            var slotID = game.Slots.FindIndex(slot => slot == request.Client.User.ID);

            Log.Info(string.Format("Client {0} reserving slot {1} in game {2}", request.Client.ID, slotID, gameID.Value));

            UserAddedNotification.Notify(request.Client, gameClient.User.ID, gameClient.User.Name);
            UserUpdatedNotification.Notify(request.Client, gameClient.User.ID);

            PlayerJoiningNotification.Notify(request.Client);

            JoiningPlayerInitiateConnectionsNotification.Notify(request.Client);
            PlayerClaimingReservationNotification.Notify(request.Client);            
        }
        public static void HandleRequest(Request request)
        {
            Log.Info(string.Format("Client {0} pre-authenticating", request.Client.ID));

            var clientData = (TdfStruct)request.Data["CDAT"];
            var clientType = (TdfInteger)clientData.Data.Find(tdf => tdf.Label == "TYPE");
            var clientService = (TdfString)clientData.Data.Find(tdf => tdf.Label == "SVCN");

            var clientInfo = (TdfStruct)request.Data["CINF"];
            var clientLocalization = (TdfInteger)clientInfo.Data.Find(tdf => tdf.Label == "LOC");

            request.Client.Type = (ClientType)clientType.Value;
            request.Client.Localization = (ulong)clientLocalization.Value;
            request.Client.Service = clientService.Value;

            // TODO: fix this
            var cids = new TdfList("CIDS", TdfBaseType.Integer, new ArrayList
            {
                //1, 25, 4, 27, 28, 6, 7, 9, 10, 11, 30720, 30721, 30722, 30723, 20, 30725, 30726, 2000
            });
            cids.List.AddRange((new ulong[] { 1, 25, 4, 27, 28, 6, 7, 9, 10, 11, 30720, 30721, 30722, 30723, 20, 30725, 30726, 2000 }).ToArray());

            var data = new List<Tdf>
            {
                new TdfInteger("ANON", 0),
                new TdfString("ASRC", "300294"),
                cids,
                new TdfString("CNGN", ""),
                new TdfStruct("CONF", new List<Tdf>
                {
                    new TdfMap("CONF", TdfBaseType.String, TdfBaseType.String, new Dictionary<object, object>
                    {
                        { "connIdleTimeout", "90s" },
                        { "defaultRequestTimeout", "80s" },
                        { "pingPeriod", "20s" },
                        { "voipHeadsetUpdateRate", "1000" },
                        { "xlspConnectionIdleTimeout", "300" }
                    })
                }),
                new TdfString("INST", request.Client.Service),
                new TdfInteger("MINR", 0),
                new TdfString("NASP", "cem_ea_id"),
                new TdfString("PILD", ""),
                new TdfString("PLAT", "pc"), // TODO: fetch from decoded data
                new TdfString("PTAG", ""),
                new TdfStruct("QOSS", new List<Tdf>
                {
                    new TdfStruct("BWPS", new List<Tdf>
                    {
                        new TdfString("PSA", "127.0.0.1"),
                        new TdfInteger("PSP", 17502),
                        new TdfString("SNA", "ams")
                    }),
                    new TdfInteger("LNP", 10),
                    new TdfMap("LTPS", TdfBaseType.String, TdfBaseType.Struct, new Dictionary<object, object>
                    {
                        { "ams", new List<Tdf>
                            {
                                new TdfString("PSA", "127.0.0.1"),
                                new TdfInteger("PSP", 17502),
                                new TdfString("SNA", "ams")
                            }
                        }
                    }),
                    new TdfInteger("SVID", 1161889797)
                }),
                new TdfString("RSRC", "300294"),
                new TdfString("SVER", "Blaze 3.15.08.0 (CL# 1060080)")
            };

            request.Reply(0, data);
        }
        public static void HandleRequest(Request request)
        {
            Log.Info(string.Format("Client {0} submitting trusted end-game report", request.Client.ID));

            request.Reply();
        }
        public static void HandleRequest(Request request)
        {
            Log.Info(string.Format("Client {0} requested club memberships", request.Client.ID));

            request.Reply();
        }