예제 #1
0
 public void GoPlayingOnline()
 {
     Status = Code.Status_POnline;
     if (Tag == 0 && MainServer.NotifyOfBots)
     {
         CmdSystem.AddLog("Bot " + Name + " has entered a room");
     }
 }
예제 #2
0
 public void GoOffline()
 {
     Status = Code.Status_Offline;
     if (Tag == 0 && MainServer.NotifyOfBots)
     {
         CmdSystem.AddLog("Bot " + Name + " has left");
     }
 }
예제 #3
0
 public void GoOnline()
 {
     Status = Code.Status_AOnline;
     if (Tag == 0 && MainServer.NotifyOfBots)
     {
         CmdSystem.AddLog("Bot " + Name + " has connected");
     }
 }
예제 #4
0
 /// <summary>
 /// If the client doesn't send any data, we will force disconnect them. This was due to errors force-closing the game,
 /// and the server thought the client was still there.
 /// </summary>
 internal void ForceDisconnect(object sender, System.Timers.ElapsedEventArgs e)
 {
     Connected = false;
     CmdSystem.AddLog(Name + " was force-disconnected.");
     DCTimer.Enabled = false;
     if (ListSlot != null)
     {
         ListSlot.GoOffline();
     }
 }
예제 #5
0
        public static void Main()
        {
            ClockTimer.RecordRunTime();

            Console.WriteLine("    ====================================================    ");
            Console.WriteLine("    Welcome to the BBLegacy Dedicated Server [prototype]    ");
            Console.WriteLine();
            Console.WriteLine("     INIFile Management Code by S.T.A. snc (C)2009-2013     ");
            Console.WriteLine("    Networking System by FatalSleep from The GMCommunity    ");
            Console.WriteLine("    ====================================================    ");
            Console.WriteLine();

            //Fetch the External IP Address, if they're not using local.
            string TheIPAddress;

            if (IsLocal == 1)
            {
                TheIPAddress = "127.0.0.1";
            }
            else
            {
                Console.Write("Fetching IP Address... ");
                TheIPAddress = getExternalIp();
                Console.WriteLine("done.");
            }
            UpdateINI Backupper = new UpdateINI(60000);

            TcpListenerSocket myTcpSocket = new TcpListenerSocket(TheIPAddress, Port, MaxClients, ReadSize, WriteSize, Alignment, PacketHeader);

            Console.WriteLine("TCP Connection Listener Established (" + TheIPAddress + " :: " + Port + ")");
            Console.WriteLine(" - The connection is set to have a maximum of " + MaxClients + " BBLegacy connections.");
            UdpServerSocket myUdpSocket = new UdpServerSocket(Port, ReadSize, WriteSize, Alignment, PacketHeader);

            Console.WriteLine("UDP Connection Listener Established (" + TheIPAddress + " :: " + Port + ")");
            string Command = "";

            Thread.Sleep(3000);

            Thread.Sleep(1000);
            Console.WriteLine("You can now type 'help' for some commands.");
            Console.WriteLine();
            Console.WriteLine("    ====================================================    ");

            while (myTcpSocket.Status == true || myUdpSocket.Status == true)
            {
                Command = Console.ReadLine();
                CmdSystem.RunCmd(Command, myTcpSocket, myUdpSocket);
            }

            ClockTimer.StopRunTime();
        }
예제 #6
0
        public static void NowBackup()
        {
            INIFile Settings = (BBLegacyServer.MainServer.SettingsFile);

            CmdSystem.AddLog("INI File Backup");
            Settings.SetValue("Server Configuration", "MaxClients", BBLegacyServer.MainServer.MaxClients);
            Settings.SetValue("Server Configuration", "Port", BBLegacyServer.MainServer.Port);
            Settings.SetValue("Server Configuration", "Local", BBLegacyServer.MainServer.IsLocal);
            Settings.SetValue("Server Configuration", "NumberOfPlayers", BBLegacyServer.MainServer.PlayerList.Count);

            var tmp = 1;

            foreach (PlayerListItem i in MainServer.PlayerList)
            {
                Settings.SetValue("PlayerListItem" + tmp, "ID", i.ID);
                Settings.SetValue("PlayerListItem" + tmp, "Name", i.Name);
                Settings.SetValue("PlayerListItem" + tmp, "Tag", i.Tag);
                tmp++;
            }

            Settings.Flush();
        }
예제 #7
0
        /// <summary>
        /// Accepts incoming client connections.
        /// </summary>
        public async void TcpAccept()
        {
            // While the server is online accept incoming client connections.
            while (Status == true)
            {
                // Attempt to process the code, if not successful, throw an exception and close the server.

                Thread.Sleep(10);

                try {
                    // If a pending client connection is found, accept the client connection.
                    if (ServerHandle.Pending() == true)
                    {
                        // If the client connection is accepted, setup the new clent.
                        TcpClientSocket NewClient = new TcpClientSocket(BufferReadSize, BufferWriteSize, BufferAlignment, PacketHeader);
                        NewClient.ClientHandle = await ServerHandle.AcceptTcpClientAsync();

                        CmdSystem.AddLog("New connection. Verifying...");
                        NewClient.ClientHandle.LingerState = new LingerOption(true, 0);
                        NewClient.ClientHandle.NoDelay     = true;
                        NewClient.DataStream = NewClient.ClientHandle.GetStream();

                        // Add the client to the server's client socket list.
                        ClientList.Add(NewClient.SocketId, NewClient);

                        // Start running the client and processing data for it, be it sending or receiving data.
                        ThreadPool.QueueUserWorkItem(myThread => ClientHandle(NewClient));
                    }
                } catch (Exception e) {
                    CmdSystem.AddLog("===== ERROR =====");
                    CmdSystem.AddLog(e.Message);
                    CmdSystem.AddLog("=================");
                }
            }

            TcpListenerClose();
        }
예제 #8
0
        /// <summary>
        /// Takes the player out of the room.
        /// </summary>
        /// <param name="Quitter">The Player to remove.</param>
        public byte Remove(TcpClientSocket Quitter)
        {
            if (Quitter.CurrentRoom == null)
            {
                return(0);
            }

            var place = players.IndexOf(Quitter) + 1;

            players.Remove(Quitter);

            try
            {
                foreach (TcpClientSocket Player in players)
                {
                    var Write = Player.WriteBuffer;
                    Write.Clear();
                    Write.WriteUByte(Player.HeaderId);
                    Write.WriteUByte(Code.UpdatePlayers);
                    Write.WriteBool(false);
                    //A player has left. Here's his place, but you might have to request the list again.
                    Write.WriteUByte((byte)place);
                    Write.SendTcp(Player.DataStream);

                    if (playstate < 3)
                    {
                        Player.Slot = (byte)(this.players.IndexOf(Player) + 1);
                    }
                }
            }
            catch { }

            Quitter.CurrentRoom = null;
            Quitter.Record      = null;
            Quitter.Slot        = 0;

            CmdSystem.AddLog(Quitter.Name + " has left room " + this.name + " (ID:" + this.id + ")");

            if (players.Count == 0)
            {
                if (tag == 0)
                {
                    playstate = 1;
                }
                else
                {
                    Dispose();
                }
            }
            else if (players.Count == 1 && playstate > 1)
            {
                EnterLobby();
            }
            else if (playstate > 1)
            {
                PlayerCompleted();
                PlayerFinished();
                PlayerReady();

                if (playstate == 2 && VoteMachine.Votes.Count >= this.players.Count)
                {
                    VoteMachine.Clock.Enabled = true;
                }
            }

            return(1);
        }
예제 #9
0
        /// <summary>
        /// Read and process packets received from the client.
        /// </summary>
        /// <param name="Player">Client socket class that is being handled.</param>
        /// <param name="myServer">Server's handle(listener) socket class.</param>
        public static void TcpPacketRead(TcpClientSocket Player, TcpListenerSocket myServer)
        {
            byte myCheck = Player.ReadBuffer.StartRead(0);

            var buff = Player.DataStream;

            //Not all functions require a writeback, but it helps to have this ready.
            var Write = Player.WriteBuffer;
            var Read  = Player.ReadBuffer;
            var File  = MainServer.SettingsFile;
            var PLID  = Player.ID.ToString();

            // Check for packets by searching for packet headers.
            while (myCheck == Player.HeaderId)
            {
                Write.Clear();
                Write.WriteUByte(Player.HeaderId);

                byte myPacketId = Read.ReadUByte();

                switch (myPacketId)
                {
                /*  To READ from the buffer...
                 *  float myFloat = Player.ReadBuffer.Readf32();
                 *  int myInteger = Player.ReadBuffer.Readu32();
                 *  string myString = Player.ReadBuffer.ReadStr();
                 *
                 *  To WRITE to the buffer and send...
                 *  Player.WriteBuffer.SetPeek( 0 );
                 *  Player.WriteBuffer.Writeu8( TcpNetwork.TcpPacketHeader );
                 *  Player.WriteBuffer.Writeu8( 254 );
                 *  Player.WriteBuffer.SendTcp( Player.DataStream );*/

                //They sent this to see if the connection works. Echo their packet back.
                case Code.ConnectionBegin:
                {
                    //Assigns the given PlayerID to this specific client. Also the name should've given their name.
                    Player.ID   = Read.ReadDouble();
                    Player.Name = Read.ReadString();
                    Player.Icon = Read.ReadUByte();
                    Player.XP   = Read.ReadUInt();
                    //Tells them that they connected.
                    Write.WriteUByte(Code.ConnectionBegin);
                    Write.WriteString(MainServer.WelcomeMessage);
                    Write.WriteBool(MainServer.CanCreateRooms);
                    CmdSystem.AddLog(Player.Name + " has connected (ID:" + Player.ID.ToString() + ")");
                    Write.SendTcp(Player.DataStream);
                    //If they're admins...
                    if (AdminList.isAdmin(Player.ID))
                    {
                        Player.Tag = 2;
                    }

                    //If they're not on the list, put them on the list.
                    //This also means that they're new players, 1st time joiners!
                    var b = false;

                    foreach (PlayerListItem i in MainServer.PlayerList)
                    {
                        if (i.ID == Player.ID)
                        {
                            b          = true;
                            Player.Tag = i.Tag;
                            i.Link(Player);
                        }
                    }

                    if (!b)
                    {
                        Player.ListSlot = new PlayerListItem();
                    }

                    Player.ListSlot.Link(Player);
                    Player.ListSlot.GoOnline();

                    MainServer.Event.PlayerConnected(Player);
                    break;
                }

                case Code.ConnectionEnd:
                {
                    Player.UserImposedDisconnection = true;
                    Player.Connected = false;
                    CmdSystem.AddLog(Player.Name + " has left");
                    if (Player.ListSlot != null)
                    {
                        Player.ListSlot.GoOffline();
                    }

                    MainServer.Event.PlayerDisconnected(Player);
                    break;
                }

                // == ADD MENU STATUS ==

                //They want to join this room. Returns ID upon success, or a negative number upon failure.
                case Code.SessionJoin:
                {
                    var id = Read.ReadUInt();

                    uint   success = 4000000004;
                    byte   pnum    = 0;
                    String nm      = " ";
                    foreach (Room i in MainServer.RoomList)
                    {
                        if (i.id == id)
                        {
                            success = i.Join(Player);
                            pnum    = (byte)i.players.Count;
                            nm      = i.name;
                            break;
                        }
                    }
                    Write.Clear();
                    Write.WriteUByte(Player.HeaderId);
                    Write.WriteUByte(Code.SessionJoin);
                    Write.WriteUInt(success);
                    Write.WriteUByte(pnum);
                    byte plst = 1;
                    if (Player.CurrentRoom != null)
                    {
                        plst = Player.CurrentRoom.playstate;
                    }
                    Write.WriteUByte(plst);
                    Write.WriteString(nm);
                    Write.SendTcp(buff);

                    if (success < 4000000000)
                    {
                        Player.ListSlot.GoPlayingOnline();
                    }
                    //Now that they know they joined, we can now auto-start the room if needed.
                    foreach (Room i in MainServer.RoomList)
                    {
                        if (i.id == id)
                        {
                            if (i.tag == 0 && i.playstate <= 2)
                            {
                                if (i.players.Count > 1 && i.playstate == 1)
                                {
                                    i.EnterVoteRoom();
                                }
                                i.Teamify();
                            }
                        }
                    }

                    MainServer.Event.PlayerJoinedRoom(Player, Player.CurrentRoom);
                    break;
                }

                case Code.SessionLeave:
                {
                    byte success = 1;
                    Room rm      = Player.CurrentRoom;

                    if (Player.CurrentRoom == null)
                    {
                        success = 0;
                    }
                    else
                    {
                        success = Player.CurrentRoom.Remove(Player);
                    }
                    Write.WriteUByte(Code.SessionLeave);
                    Write.WriteUByte(success);
                    Write.SendTcp(Player.DataStream);

                    if (success > 0)
                    {
                        Player.ListSlot.GoOnline();
                        MainServer.Event.PlayerLeftRoom(Player, rm);
                    }

                    break;
                }

                //Creates a session, returning room ID if the operation was successful.
                case Code.SessionCreate:
                {
                    //Host, Name, Mode, Team, Team Number, Minutes, Max Players
                    var rs1 = Read.ReadString();
                    var ub2 = Read.ReadUByte();
                    var bo3 = Read.ReadBool();
                    var ub4 = Read.ReadUByte();
                    var ub5 = Read.ReadUByte();
                    var ub6 = Read.ReadUByte();

                    var bo7  = Read.ReadBool();
                    var ub8  = Read.ReadUByte();
                    var ub9  = Read.ReadUByte();
                    var ub10 = Read.ReadUByte();
                    var ub11 = Read.ReadUByte();
                    var ub12 = Read.ReadUByte();

                    Write.WriteUByte(Code.SessionCreate);

                    if (MainServer.CanCreateRooms && Player.CurrentRoom == null)
                    {
                        Room rm = new Room(Player, rs1, ub2, bo3, ub4, ub5, ub6);
                        Write.WriteBool(true);
                        Write.WriteUInt(rm.id);
                        Write.WriteString(rm.name);

                        rm.is_custom_items = bo7;
                        rm.citm_1          = ub8;
                        rm.citm_2          = ub9;
                        rm.citm_3          = ub10;
                        rm.citm_4          = ub11;
                        rm.citm_5          = ub12;
                        //So for special admins, we should highlight their room by making it a special tagged room.
                        if (AdminList.isAdmin(Player.ID))
                        {
                            rm.tag = 2;
                        }

                        Player.ListSlot.GoPlayingOnline();
                    }
                    else
                    {
                        Write.WriteBool(false);
                    }

                    Write.SendTcp(buff);

                    MainServer.Event.PlayerCreatedRoom(Player, Player.CurrentRoom);
                    break;
                }

                //Not sent by client.
                case Code.UpdatePlayers: break;

                //Host-invoked room starting.
                case Code.StartRoom:
                {
                    var rm = Player.CurrentRoom;

                    if (rm == null || rm.tag == 0 || rm.players.IndexOf(Player) != 0 || rm.playstate != 1)
                    {
                        break;
                    }

                    rm.EnterVoteRoom();
                    break;
                }

                //A player changes his or her character in the lobby. Let the room tell the others.
                case Code.ChangeCharacter:
                {
                    var c = Read.ReadUByte();

                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    Player.CurrentRoom.ChangeCharacter(Player, c);
                    MainServer.Event.PlayerChangedChar(Player, Player.Character);
                    break;
                }

                //A player changes his or her team. Let the room tell the others.
                case Code.ChangeTeam:
                {
                    var t = Read.ReadUByte();

                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    Player.CurrentRoom.ChangeTeam(Player, t);
                    MainServer.Event.PlayerChangedTeam(Player, Player.Team);
                    break;
                }

                //The host changes these battle settings. Let their room update and then tell everyone.
                case Code.ChangeBattleSettings:
                {
                    break;
                }

                //Not sent by client.
                case Code.RoomState: break;

                //The player requests the information of another player with this ID.
                case Code.PlayerInfo:
                {
                    break;
                }

                //Simple packet to say that we're responding. Can be used for ping.
                case Code.IAmHere:
                {
                    Write.WriteUByte(Code.IAmHere);
                    Write.SendTcp(buff);
                    break;
                }

                //The player wants a list of all open rooms.
                case Code.RequestRoomList:
                {
                    Write.WriteUByte(Code.RequestRoomList);
                    //Send just their IDs and a 0 at the end. The game will ask later.
                    //The order will go like SERVER ROOMS; OPEN PLAYER ROOMS; CLOSED PLAYER ROOMS.
                    //The extra bool reports their size (big or small).
                    foreach (Room i in MainServer.RoomList)
                    {
                        if (i.visible && i.tag == 0)
                        {
                            Write.WriteUInt(i.id); Write.WriteBool(true);
                        }
                    }

                    foreach (Room i in MainServer.RoomList)
                    {
                        if (i.visible && i.tag == 2 && i.playstate == 1)
                        {
                            Write.WriteUInt(i.id); Write.WriteBool(true);
                        }
                    }

                    foreach (Room i in MainServer.RoomList)
                    {
                        if (i.visible && i.tag == 1 && i.playstate == 1)
                        {
                            Write.WriteUInt(i.id); Write.WriteBool(false);
                        }
                    }

                    foreach (Room i in MainServer.RoomList)
                    {
                        if (i.visible && i.tag == 2 && i.playstate != 1)
                        {
                            Write.WriteUInt(i.id); Write.WriteBool(true);
                        }
                    }

                    foreach (Room i in MainServer.RoomList)
                    {
                        if (i.visible && i.tag == 1 && i.playstate != 1)
                        {
                            Write.WriteUInt(i.id); Write.WriteBool(false);
                        }
                    }

                    Write.WriteUInt(0);
                    Write.SendTcp(buff);
                    break;
                }

                //The player wants this specific room's information.
                case Code.RequestRoomInformation:
                {
                    var rm = Read.ReadUInt();

                    var found = false;

                    if (MainServer.RoomList.Count == 0)
                    {
                        break;
                    }

                    Write.WriteUByte(Code.RequestRoomInformation);

                    foreach (Room i in MainServer.RoomList)
                    {
                        if (i.id == rm)
                        {
                            Write.WriteUInt(i.id);
                            Write.WriteString(i.name);
                            Write.WriteString(i.host_name);
                            Write.WriteSByte(i.tag);
                            Write.WriteUByte((byte)i.players.Count);
                            Write.WriteUByte(i.maxplayers);
                            Write.WriteUByte(i.mode);
                            Write.WriteBool(i.teams);
                            Write.WriteUByte(i.playstate);
                            Write.WriteUByte(i.maxteams);
                            Write.WriteUByte(i.minutes);
                            found = true;
                            break;
                        }
                    }
                    if (found)
                    {
                        Write.SendTcp(buff);
                    }
                    else
                    {
                        Write.Clear();
                    }

                    break;
                }

                //The player wants a list of all players.
                case Code.RequestPlayerList:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }
                    Player.CurrentRoom.SendPlayerList(Player);
                    break;
                }

                //Packet echo'ing.
                case Code.SendMe:
                {
                    Write.WriteUByte(Code.SendMe);
                    byte   DataType = Read.ReadUByte();
                    int    val;
                    uint   uval;
                    float  valf;
                    double vald;
                    Write.WriteUByte(DataType);
                    switch (DataType)
                    {
                    case 1: val = Read.ReadUByte(); Write.WriteUByte((byte)val); CmdSystem.AddLog(Player.Name + " echo request: " + (byte)val); break;

                    case 2: val = Read.ReadSByte(); Write.WriteSByte((sbyte)val); CmdSystem.AddLog(Player.Name + " echo request: " + (sbyte)val); break;

                    case 3: val = Read.ReadUShort(); Write.WriteUShort((ushort)val); CmdSystem.AddLog(Player.Name + " echo request: " + (ushort)val); break;

                    case 4: val = Read.ReadSShort(); Write.WriteSShort((short)val); CmdSystem.AddLog(Player.Name + " echo request: " + (short)val); break;

                    case 5: uval = Read.ReadUInt(); Write.WriteUInt(uval); CmdSystem.AddLog(Player.Name + " echo request: " + uval); break;

                    case 6: val = (int)Read.ReadSInt(); Write.WriteSInt(val); CmdSystem.AddLog(Player.Name + " echo request: " + val); break;

                    case 7: valf = Read.ReadFloat(); Write.WriteFloat(valf); CmdSystem.AddLog(Player.Name + " echo request: " + valf); break;

                    case 8: vald = Read.ReadDouble(); Write.WriteDouble(vald); CmdSystem.AddLog(Player.Name + " echo request: " + vald); break;

                    default: Read.ReadUByte(); Write.WriteUByte(0); CmdSystem.AddLog(Player.Name + " blank echo request."); break;
                    }
                    Write.SendTcp(Player.DataStream);
                    break;
                }

                //A player sends a vote to his room.
                case Code.Vote:
                {
                    byte stg = Read.ReadUByte();

                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    Player.CurrentRoom.AcceptVote(Player, stg);
                    break;
                }

                //The player has finished loading and is ready to start the battle.
                case Code.BattleReady:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }
                    Player.CurrentRoom.PlayerReady();
                    break;
                }

                /*
                 * NOW, for the next few codes, the server is simply a relayer to all
                 * the other players. It doesn't really keep any of this data, which
                 * we should in the future so we can keep some spam/hack control.
                 */

                //The player moved, let everyone else know.
                case Code.Movement:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    var ss1 = Read.ReadSShort();
                    var ss2 = Read.ReadSShort();
                    var ub3 = Read.ReadUByte();

                    Write.WriteUByte(Code.Movement);
                    Write.WriteUByte(Player.Slot);

                    Write.WriteSShort(ss1);
                    Write.WriteSShort(ss2);
                    Write.WriteUByte(ub3);

                    foreach (TcpClientSocket Others in Player.CurrentRoom.players)
                    {
                        if (!Others.Equals(Player))
                        {
                            Write.SendTcp(Others.DataStream);
                        }
                    }
                    break;
                }

                //The player stopped, let everyone else know.
                case Code.Stopment:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    var ss1 = Read.ReadSShort();
                    var ss2 = Read.ReadSShort();

                    Write.WriteUByte(Code.Stopment);
                    Write.WriteUByte(Player.Slot);

                    Write.WriteSShort(ss1);
                    Write.WriteSShort(ss2);

                    foreach (TcpClientSocket Others in Player.CurrentRoom.players)
                    {
                        if (!Others.Equals(Player))
                        {
                            Write.SendTcp(Others.DataStream);
                        }
                    }
                    break;
                }

                //The player used an item, let everyone else know.
                case Code.Item:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    var ub1 = Read.ReadUByte();
                    var bo1 = Read.ReadBool();
                    var ss2 = Read.ReadSShort();
                    var ss3 = Read.ReadSShort();
                    var ff4 = Read.ReadFloat();
                    var ff5 = Read.ReadFloat();

                    Write.WriteUByte(Code.Item);
                    Write.WriteUByte(Player.Slot);

                    Write.WriteUByte(ub1);
                    Write.WriteBool(bo1);
                    Write.WriteSShort(ss2);
                    Write.WriteSShort(ss3);
                    Write.WriteFloat(ff4);
                    Write.WriteFloat(ff5);

                    foreach (TcpClientSocket Others in Player.CurrentRoom.players)
                    {
                        if (!Others.Equals(Player))
                        {
                            Write.SendTcp(Others.DataStream);
                        }
                    }

                    MainServer.Event.PlayerUsedItem(Player, ub1);
                    break;
                }

                //The player got hit, let everyone else know.
                case Code.Hit:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    var ub1 = Read.ReadUByte();
                    var ss2 = Read.ReadSShort();
                    var ss3 = Read.ReadSShort();
                    var ff4 = Read.ReadFloat();
                    var ff5 = Read.ReadFloat();
                    var ff6 = Read.ReadFloat();

                    Write.WriteUByte(Code.Hit);
                    Write.WriteUByte(Player.Slot);

                    Write.WriteUByte(ub1);
                    Write.WriteSShort(ss2);
                    Write.WriteSShort(ss3);
                    Write.WriteFloat(ff4);
                    Write.WriteFloat(ff5);
                    Write.WriteFloat(ff6);

                    foreach (TcpClientSocket Others in Player.CurrentRoom.players)
                    {
                        if (!Others.Equals(Player))
                        {
                            Write.SendTcp(Others.DataStream);
                        }
                    }

                    MainServer.Event.PlayerHit(Player, ub1, ff6);
                    break;
                }

                //The player got killed, let everyone else know.
                case Code.Death:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    var ss1 = Read.ReadSShort();
                    var ss2 = Read.ReadSShort();
                    var ff3 = Read.ReadFloat();
                    var ub4 = Read.ReadUByte();

                    Write.WriteUByte(Code.Death);
                    Write.WriteUByte(Player.Slot);

                    Write.WriteSShort(ss1);
                    Write.WriteSShort(ss2);
                    Write.WriteFloat(ff3);
                    Write.WriteUByte(ub4);

                    foreach (TcpClientSocket Others in Player.CurrentRoom.players)
                    {
                        if (!Others.Equals(Player))
                        {
                            Write.SendTcp(Others.DataStream);
                        }
                    }

                    MainServer.Event.PlayerDeath(Player, ff3);
                    break;
                }

                //The player got a point, let everyone else know.
                case Code.Score:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    var ub1 = Read.ReadUByte();
                    var ub2 = Read.ReadUByte();
                    var ss3 = Read.ReadSShort();

                    Write.WriteUByte(Code.Score);

                    Write.WriteUByte(ub1);
                    Write.WriteUByte(ub2);
                    Write.WriteSShort(ss3);

                    foreach (TcpClientSocket Others in Player.CurrentRoom.players)
                    {
                        if (!Others.Equals(Player))
                        {
                            Write.SendTcp(Others.DataStream);
                        }
                    }

                    MainServer.Event.PlayerScored(Player, ss3);
                    break;
                }

                //Absolute Score Update
                case Code.AbsoluteScore:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    var ss1 = Read.ReadSShort();

                    Write.WriteUByte(Code.AbsoluteScore);
                    Write.WriteUByte(Player.Slot);

                    Write.WriteSShort(ss1);

                    foreach (TcpClientSocket Others in Player.CurrentRoom.players)
                    {
                        if (!Others.Equals(Player))
                        {
                            Write.SendTcp(Others.DataStream);
                        }
                    }
                    break;
                }

                //The player dropped coins, let everyone else know.
                case Code.CoinDrop:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    var ub1 = Read.ReadUByte();

                    Write.WriteUByte(Code.CoinDrop);
                    Write.WriteUByte(Player.Slot);

                    Write.WriteUByte(ub1);

                    foreach (TcpClientSocket Others in Player.CurrentRoom.players)
                    {
                        if (!Others.Equals(Player))
                        {
                            Write.SendTcp(Others.DataStream);
                        }
                    }
                    break;
                }

                //The player dropped coins, let everyone else know.
                case Code.ItemDrop:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    var ss1 = Read.ReadSShort();
                    var ss2 = Read.ReadSShort();
                    var fl3 = Read.ReadFloat();
                    var ub4 = Read.ReadUByte();
                    var ub5 = Read.ReadUByte();
                    var ub6 = Read.ReadUByte();

                    Write.WriteUByte(Code.ItemDrop);
                    Write.WriteUByte(Player.Slot);

                    Write.WriteSShort(ss1);
                    Write.WriteSShort(ss2);
                    Write.WriteFloat(fl3);
                    Write.WriteUByte(ub4);
                    Write.WriteUByte(ub5);
                    Write.WriteUByte(ub6);

                    foreach (TcpClientSocket Others in Player.CurrentRoom.players)
                    {
                        if (!Others.Equals(Player))
                        {
                            Write.SendTcp(Others.DataStream);
                        }
                    }
                    break;
                }

                //The player's purple spawned, let everyone else know.
                case Code.PurpleSpawn:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    var ss1 = Read.ReadSShort();
                    var ss2 = Read.ReadSShort();

                    Write.WriteUByte(Code.PurpleSpawn);
                    Write.WriteUByte(Player.Slot);

                    Write.WriteSShort(ss1);
                    Write.WriteSShort(ss2);

                    foreach (TcpClientSocket Others in Player.CurrentRoom.players)
                    {
                        if (!Others.Equals(Player))
                        {
                            Write.SendTcp(Others.DataStream);
                        }
                    }
                    break;
                }

                //The player has finished, here are their stats.
                case Code.PlayerRecap:
                {
                    if (Player.Record == null || Player.CurrentRoom == null)
                    {
                        break;
                    }

                    Player.Record.HitsGiven   = Read.ReadUShort();
                    Player.Record.Kills       = Read.ReadUShort();
                    Player.Record.Items       = Read.ReadUShort();
                    Player.Record.HitsTaken   = Read.ReadUShort();
                    Player.Record.Deaths      = Read.ReadUShort();
                    Player.Record.CoinsGained = Read.ReadUShort();
                    Player.Record.CoinsLost   = Read.ReadUShort();

                    Write.WriteUByte(Code.PlayerRecap);
                    Write.WriteUByte(Player.Slot);
                    Player.CurrentRoom.DistributeStats(Player);
                    break;
                }

                //The player has to send their statistics for proper attack, defense, etc.
                case Code.PlayerStats:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    var ub1 = Read.ReadUByte();
                    var ub2 = Read.ReadUByte();
                    var ub3 = Read.ReadUByte();
                    var ub4 = Read.ReadUByte();

                    Write.WriteUByte(Code.PlayerStats);
                    Write.WriteUByte(Player.Slot);

                    Write.WriteUByte(ub1);
                    Write.WriteUByte(ub2);
                    Write.WriteUByte(ub3);
                    Write.WriteUByte(ub4);

                    foreach (TcpClientSocket Others in Player.CurrentRoom.players)
                    {
                        if (!Others.Equals(Player))
                        {
                            Write.SendTcp(Others.DataStream);
                        }
                    }
                    break;
                }

                //They sent a Battle Complete packet and are now waiting for everyone else to finish.
                case Code.BattleEnd:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    Player.CurrentRoom.PlayerFinished();
                    break;
                }

                //They pressed the Next Battle button and are waiting for everyone else to do the same.
                case Code.BattleComplete:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    Player.CurrentRoom.PlayerCompleted();
                    break;
                }

                //They asked for an updated Server Message pack.
                case Code.ServerMessages:
                {
                    Write.WriteUByte(Code.ServerMessages);
                    Write.WriteString(MainServer.GoodbyeMessage);
                    Write.WriteString(MainServer.DCMessage);
                    Write.WriteString(MainServer.KickMessage);
                    Write.WriteString(MainServer.InfoMessage);
                    Write.SendTcp(Player.DataStream);
                    break;
                }

                //Update their XP. Simple as that.
                case Code.UpdateXP:
                {
                    Player.XP = Read.ReadUInt();
                    break;
                }

                //Yes or no?
                case Code.CanICreateRoomsYet:
                {
                    Write.WriteUByte(Code.CanICreateRoomsYet);
                    Write.WriteBool(MainServer.CanCreateRooms);
                    Write.SendTcp(Player.DataStream);
                    break;
                }

                //
                case Code.PlayerList:
                {
                    Write.WriteUByte(Code.PlayerList);

                    foreach (PlayerListItem i in MainServer.PlayerList)
                    {
                        if (i.Status == Code.Status_AOnline)
                        {
                            Write.WriteBool(true); Write.WriteDouble(i.ID); Write.WriteUByte(i.Tag); Write.WriteUByte(i.Status); Write.WriteString(i.Name);
                        }
                    }

                    foreach (PlayerListItem i in MainServer.PlayerList)
                    {
                        if (i.Status == Code.Status_POnline)
                        {
                            Write.WriteBool(true); Write.WriteDouble(i.ID); Write.WriteUByte(i.Tag); Write.WriteUByte(i.Status); Write.WriteString(i.Name);
                        }
                    }

                    foreach (PlayerListItem i in MainServer.PlayerList)
                    {
                        if (i.Status == Code.Status_Offline)
                        {
                            Write.WriteBool(true); Write.WriteDouble(i.ID); Write.WriteUByte(i.Tag); Write.WriteUByte(i.Status); Write.WriteString(i.Name);
                        }
                    }

                    Write.WriteBool(false);
                    Write.SendTcp(Player.DataStream);
                    break;
                }

                case Code.PL_Single:
                {
                    var id = Read.ReadDouble();

                    foreach (PlayerListItem i in MainServer.PlayerList)
                    {
                        if (i.ID == id)
                        {
                            Write.WriteUByte(Code.PL_Single);
                            Write.WriteDouble(id);
                            Write.WriteUByte(i.Status);
                            Write.SendTcp(Player.DataStream);
                        }
                    }
                }
                break;

                //The player dropped coins, let everyone else know.
                case Code.ItemInvoke:
                {
                    if (Player.CurrentRoom == null)
                    {
                        break;
                    }

                    var ub1 = Read.ReadUByte();
                    var ss2 = Read.ReadSShort();
                    var ss3 = Read.ReadSShort();

                    Write.WriteUByte(Code.ItemInvoke);
                    Write.WriteUByte(Player.Slot);

                    Write.WriteUByte(ub1);
                    Write.WriteSShort(ss2);
                    Write.WriteSShort(ss3);

                    foreach (TcpClientSocket Others in Player.CurrentRoom.players)
                    {
                        if (!Others.Equals(Player))
                        {
                            Write.SendTcp(Others.DataStream);
                        }
                    }
                    break;
                }

                case Code.Command:
                    var s = Read.ReadString();
                    Console.WriteLine("USER INVOKED COMMAND:");
                    Console.WriteLine("    " + s);
                    Console.WriteLine("    by " + Player.Name);
                    var done = true;
                    if (Player.Tag != 2)
                    {
                        done = false;
                        CmdSystem.AddLog("User missing permissions, access denied");
                    }
                    else
                    {
                        CmdSystem.RunCmd(s);
                        done = CmdSystem.LastCommandSuccessful;
                    }
                    Write.WriteUByte(Code.Command);
                    Write.WriteBool(done);
                    Write.WriteString(CmdSystem.LastLog);
                    Write.SendTcp(Player.DataStream);
                    break;

                default: break;
                }

                // Back-up the read/peek position of the buffer and check for a secondary/merged packet.
                int myHeaderId = Player.ReadBuffer.EndRead(false);
                myCheck = ( byte )((myHeaderId != -1) ? myHeaderId : ~myHeaderId);
            }
        }
예제 #10
0
        public static void RunCmd(string myCmd)
        {
            LastCommandSuccessful = true;

            long   RunTime = ClockTimer.GetRunTime();
            string command = myCmd.ToLower();

            TcpListenerSocket myTcpServer = MainServer.myTcpSocket;
            UdpServerSocket   myUdpServer = MainServer.myUdpSocket;

            //Special parameter-needing commands
            if (command.StartsWith("setmsg welcome "))
            {
                MainServer.WelcomeMessage = myCmd.Substring(15); MessageUpdater.SendMessagePacket(); CmdSystem.AddLog("Welcome message set to '" + MainServer.WelcomeMessage + "'"); return;
            }
            if (command.StartsWith("setmsg kick "))
            {
                MainServer.KickMessage = myCmd.Substring(12); MessageUpdater.SendMessagePacket(); CmdSystem.AddLog("Kick message set to '" + MainServer.KickMessage + "'"); return;
            }
            if (command.StartsWith("setmsg dc "))
            {
                MainServer.DCMessage = myCmd.Substring(10); MessageUpdater.SendMessagePacket(); CmdSystem.AddLog("Disconnected message set to '" + MainServer.DCMessage + "'"); return;
            }
            if (command.StartsWith("setmsg goodbye "))
            {
                MainServer.GoodbyeMessage = myCmd.Substring(15); MessageUpdater.SendMessagePacket(); CmdSystem.AddLog("Disconnected message set to '" + MainServer.GoodbyeMessage + "'"); return;
            }
            if (command.StartsWith("setmsg info "))
            {
                MainServer.InfoMessage = myCmd.Substring(12); MessageUpdater.SendMessagePacket(); CmdSystem.AddLog("Info message set to '" + MainServer.InfoMessage + "'"); return;
            }
            if (command.StartsWith("mm "))
            {
                MessageUpdater.BroadcastMessage(myCmd.Substring(3)); CmdSystem.AddLog("BROADCASTED: " + myCmd.Substring(3)); return;
            }

            if (command.StartsWith("closeroom "))
            {
                foreach (Room i in MainServer.RoomList)
                {
                    if (i.id == Int32.Parse(myCmd.Substring(10)))
                    {
                        i.Dispose();
                        CmdSystem.AddLog("Room " + myCmd.Substring(10) + " disposed");
                        return;
                    }
                }
                CmdSystem.AddLog("Could not find room " + myCmd.Substring(10));
                return;
            }
            if (command.StartsWith("kick "))
            {
                foreach (KeyValuePair <long, TcpClientSocket> i in TcpListenerSocket.ClientList)
                {
                    if (i.Value.SocketId == Int32.Parse(myCmd.Substring(5)))
                    {
                        var Write = i.Value.WriteBuffer;
                        Write.Clear();
                        Write.WriteUByte(i.Value.HeaderId);
                        Write.WriteUByte(Code.ConnectionEnd);
                        Write.SendTcp(i.Value.DataStream);

                        i.Value.UserImposedDisconnection = true;
                        i.Value.Connected = false;

                        CmdSystem.AddLog("Player " + i.Value.Name + " has been kicked");
                        return;
                    }
                }
                CmdSystem.AddLog("Could not find player with socket " + myCmd.Substring(5));
                return;
            }
            if (command.StartsWith("admin "))
            {
                foreach (KeyValuePair <long, TcpClientSocket> i in TcpListenerSocket.ClientList)
                {
                    if (i.Value.ID == Int32.Parse(myCmd.Substring(6)))
                    {
                        if (i.Value.Tag == 2)
                        {
                            i.Value.Tag = 1;
                        }
                        else
                        {
                            i.Value.Tag = 2;
                        }

                        CmdSystem.AddLog("Player " + i.Value.Name + " admin: " + (i.Value.Tag == 2));
                        return;
                    }
                }
                CmdSystem.AddLog("Could not find player with ID " + myCmd.Substring(6));
                return;
            }

            //Normal commands
            switch (command)
            {
            case "help":
                Console.WriteLine("========================");
                Console.WriteLine();
                Console.WriteLine("    " + "help - displays list of commands");
                Console.WriteLine("    " + "tcpstop - ends TCP communications");
                Console.WriteLine("    " + "udpstop - ends UDP communications");
                Console.WriteLine("    " + "count - counts all the TCP connections");
                Console.WriteLine("    " + "status - tells how the server is doing");
                Console.WriteLine("    " + "unlog - clears the log");
                Console.WriteLine("    " + "clear - clears the console");
                Console.WriteLine("    " + "update - force update ini file");
                Console.WriteLine();
                Console.WriteLine("    " + "roomlist - displays a list of all open rooms");
                Console.WriteLine("    " + "players - lists all online players");
                Console.WriteLine("    " + "room solo - Creates a solo play room for all modes");
                Console.WriteLine("    " + "room team - Creates a team play room for all modes");
                Console.WriteLine();
                Console.WriteLine("    " + "clear servers - closes all server rooms");
                Console.WriteLine("    " + "clear rooms - closes all rooms");
                Console.WriteLine("    " + "kickall - kicks everyone off the server");
                Console.WriteLine("    " + "clear pl - clears the player list");
                Console.WriteLine("    " + "closeroom [roomID]");
                Console.WriteLine("    " + "kick [socketID]");
                Console.WriteLine("    " + "admin [playerid] - toggle admin status of this user");
                Console.WriteLine();
                Console.WriteLine("    " + "setmsg welcome [message]");
                Console.WriteLine("    " + "setmsg goodbye [message]");
                Console.WriteLine("    " + "setmsg kick [message]");
                Console.WriteLine("    " + "setmsg dc [message]");
                Console.WriteLine("    " + "setmsg info [message]");
                Console.WriteLine("    " + "toggle makerooms - toggles player creation of rooms");
                Console.WriteLine("    " + "toggle notifybots - toggles notification of tag 0 players");
                Console.WriteLine();
                Console.WriteLine("========================");
                break;

            case "tcpstop":
                if (myTcpServer != null && myTcpServer.Status == true)
                {
                    myTcpServer.Status = false;
                    Console.WriteLine("Time(" + RunTime.ToString() + ") :: TCP Server Stopped");
                }
                break;

            case "udpstop":
                if (myUdpServer != null && myUdpServer.Status == true)
                {
                    myUdpServer.Status = false;
                    Console.WriteLine("Time(" + RunTime.ToString() + ") :: UDP Server Stopped");
                }
                break;

            case "exit":
            {
                if (myTcpServer != null && myTcpServer.Status == true)
                {
                    myTcpServer.Status = false;
                    Console.WriteLine("Time(" + RunTime.ToString() + ") :: TCP Server Stopped");
                }
                if (myUdpServer != null && myUdpServer.Status == true)
                {
                    myUdpServer.Status = false;
                    Console.WriteLine("Time(" + RunTime.ToString() + ") :: UDP Server Stopped");
                }

                MainServer.SettingsFile.Flush();

                break;
            }

            case "status":
                Console.WriteLine("Time(" + RunTime.ToString() + ") :: Server Status:");
                if (myTcpServer != null && myTcpServer.Status == true)
                {
                    Console.WriteLine("    :: TCP Status(" + myTcpServer.Status.ToString() + ")");
                }
                if (myUdpServer != null && myUdpServer.Status == true)
                {
                    Console.WriteLine("    :: UDP Status(" + myUdpServer.Status.ToString() + ")");
                }
                if (myTcpServer != null && myTcpServer.Status == true)
                {
                    Console.WriteLine("    :: Client Count(" + TcpListenerSocket.ClientList.Count.ToString() + ")");
                }
                break;

            case "unlog":
                CmdLog.Clear();
                Console.WriteLine(RunTime.ToString() + "ms :: Log Cleared");
                break;

            case "clear":
                Console.Clear();
                Console.WriteLine(RunTime.ToString() + "ms :: Console Cleared");
                break;

            case "clear pl":
                MainServer.PlayerList.Clear();
                Console.WriteLine(RunTime.ToString() + "ms :: Player List Cleared");
                break;

            case "update":
                UpdateINI.NowBackup();
                Console.WriteLine(RunTime.ToString() + "ms :: INI Update Complete");
                break;

            case "room solo":
                var rm = new Room();
                rm.teams = false;
                break;

            case "room team":
                var room = new Room();
                room.teams = true;
                break;

            case "players":
                if (TcpListenerSocket.ClientList.Count == 0)
                {
                    Console.WriteLine("    No players are connected!");
                    break;
                }
                Console.WriteLine("Current Player List");
                foreach (KeyValuePair <long, TcpClientSocket> Player in TcpListenerSocket.ClientList)
                {
                    Console.WriteLine("   (" + Player.Value.SocketId + ") id:" + Player.Value.ID + " n:" + Player.Value.Name);
                }
                break;

            case "roomlist":
                if (MainServer.RoomList.Count == 0)
                {
                    Console.WriteLine("    No rooms are currently open!");
                    break;
                }
                Console.WriteLine("Current Room List");
                foreach (Room Room in MainServer.RoomList)
                {
                    Console.WriteLine("   " + Room.id + ": " + Room.name + " hosted by " + Room.host_name);
                    Console.WriteLine("      " + "Mode: " + Room.mode + " | "
                                      + "Teams: " + Room.teams + " | "
                                      + "Mins: " + Room.minutes + " | "
                                      + "MaxPlyrs: " + Room.maxplayers + " | "
                                      + "RoomState: " + Room.playstate + " | ");
                    foreach (TcpClientSocket Player in Room.players)
                    {
                        Console.WriteLine("      " + Player.Slot + ". " + Player.Name + "| C: " + Player.Character + (Room.teams? " T: " + Player.Team : ""));
                    }
                    Console.WriteLine();
                }
                break;

            case "clear rooms":
                try
                {
                    List <Room> Rooms = new List <Room>(MainServer.RoomList);
                    foreach (Room i in Rooms)
                    {
                        i.Dispose();
                    }
                    CmdSystem.AddLog("    All rooms have been cleared, and players kicked out to the online lobby.");
                }
                catch
                {
                    CmdSystem.AddLog("    Failed to clear roomlist.");
                }
                MainServer.RoomNumb = 0;
                break;

            case "clear servers":
                try
                {
                    List <Room> Rooms = new List <Room>(MainServer.RoomList);
                    foreach (Room i in Rooms)
                    {
                        if (i.tag == 0)
                        {
                            i.Dispose();
                        }
                    }
                    CmdSystem.AddLog("    All server rooms have been cleared, and their players kicked out to the main menu.");
                }
                catch
                {
                    CmdSystem.AddLog("    Failed to clear.");
                }
                MainServer.RoomNumb = 0;
                break;

            case "kickall":
                try
                {
                    foreach (KeyValuePair <long, TcpClientSocket> Player in TcpListenerSocket.ClientList)
                    {
                        var Write = Player.Value.WriteBuffer;
                        Write.Clear();
                        Write.WriteUByte(Player.Value.HeaderId);
                        Write.WriteUByte(Code.ConnectionEnd);
                        Write.SendTcp(Player.Value.DataStream);

                        Player.Value.UserImposedDisconnection = true;
                        Player.Value.Connected = false;
                    }
                    CmdSystem.AddLog("    All players have been kicked.");
                }
                catch
                { CmdSystem.AddLog("    Kicking failed."); }
                break;

            case "toggle makerooms":
                MainServer.CanCreateRooms = !MainServer.CanCreateRooms;
                Console.WriteLine("    Player creation of rooms set to " + MainServer.CanCreateRooms + ".");
                break;

            case "toggle notifybots":
                MainServer.NotifyOfBots = !MainServer.NotifyOfBots;
                Console.WriteLine("    Bot notifications set to " + MainServer.NotifyOfBots + ".");
                break;

            default: CmdSystem.AddLog("    Unknown command"); LastCommandSuccessful = false;  break;
            }
        }
        /// <summary>
        /// Read and process packets received from the client.
        /// </summary>
        /// <param name="myClient">Client socket class that is being handled.</param>
        // <param name="myClientList">List of clients from the server.</param>
        /// <param name="myServer">Server's handle(listener) socket class.</param>
        // <param name="myServerSocketId">Socket ID of the server.</param>
        public static void TcpPacketRead(TcpClientSocket myClient, TcpListenerSocket myServer)
        {
            byte myCheck = myClient.ReadBuffer.StartRead(0);

            var WriteBuff = myClient.WriteBuffer;
            var ReadBuff  = myClient.ReadBuffer;
            var File      = MainServer.SettingsFile;
            var ID        = myClient.PlayerID.ToString();

            // Check for packets by searching for packet headers.
            while (myCheck == myClient.HeaderId)
            {
                byte myPacketId = ReadBuff.Readu8();

                switch (myPacketId)
                {
                /*  To READ from the buffer...
                 *  float myFloat = myClient.ReadBuffer.Readf32();
                 *  int myInteger = myClient.ReadBuffer.Readu32();
                 *  string myString = myClient.ReadBuffer.ReadStr();
                 *
                 *  To WRITE to the buffer and send...
                 *  myClient.WriteBuffer.SetPeek( 0 );
                 *  myClient.WriteBuffer.Writeu8( TcpNetwork.TcpPacketHeader );
                 *  myClient.WriteBuffer.Writeu8( 254 );
                 *  myClient.WriteBuffer.SendTcp( myClient.DataStream );*/

                //They sent this to see if the connection works. Echo their packet back.
                case (Code.ConnectionBegin):
                {
                    //Assigns the given PlayerID to this specific client. Also the name should've given their name.
                    myClient.PlayerID   = ReadBuff.Readf64();
                    myClient.PlayerName = ReadBuff.ReadStr();
                    //Tells them that they connected.
                    WriteBuff.SetPeek(0);
                    WriteBuff.Writeu8(myClient.HeaderId);
                    WriteBuff.Writeu8(Code.ConnectionBegin);
                    WriteBuff.WriteStr(MainServer.WelcomeMessage);
                    CmdSystem.AddLog("BBLegacy Client Connected (" + myClient.PlayerName + " [" + myClient.PlayerID.ToString() + "])");
                    WriteBuff.SendTcp(myClient.DataStream);
                    //Update their online status.
                    File.SetValue(myClient.PlayerID.ToString(), "MenuStatus", Code.Status_AOnline);
                    File.SetValue(myClient.PlayerID.ToString(), "Name", myClient.PlayerName);
                    break;
                }

                case (Code.ConnectionEnd):
                {
                    myClient.TcpClientClose();
                    CmdSystem.AddLog("Client " + myClient.SocketId.ToString() + " Requested Disconnection -- Granted.");
                    break;
                }

                case (Code.SessionCreate):
                {
                    //You're actually creating a session :D
                    //It's just like joining one, but you make it, then join.
                    byte RoomId = 0, Failed = 0;
                    var  RoomName     = ReadBuff.ReadStr();
                    var  RoomHostName = myClient.PlayerName;
                    //Can't make one while inside one.
                    if (myClient.isInSession)
                    {
                        Failed = 1;
                    }
                    else
                    {
                        for (byte i = 0; i < 255; i++)
                        {
                            if (!MainServer.SessionNumberList.Contains(i))
                            {
                                //Found a free room.
                                RoomId = i;
                                MainServer.SessionNumberList.Add(i);
                                break;
                            }
                            if (i == 255)
                            {
                                Failed = 2; //WHAT. there's more than 250 rooms?
                            }
                        }
                    }

                    WriteBuff.SetPeek(0);
                    WriteBuff.Writeu8(myClient.HeaderId);
                    WriteBuff.Writeu8(Code.SessionCreate);
                    WriteBuff.Writeu8(Failed);
                    WriteBuff.SendTcp(myClient.DataStream);

                    break;
                }

                case (Code.SessionJoin):
                {
                    //Request to Join a Room. Which room? This room!
                    var     id     = ReadBuff.Readu8();
                    Session RoomId = MainServer.SessionList.Find(e => e.GetID() == id);
                    //Cannot join a room while in another.
                    if (myClient.isInSession)
                    {
                        WriteBuff.SetPeek(0);
                        WriteBuff.Writeu8(myClient.HeaderId);
                        WriteBuff.Writeu8(Code.SessionJoin);
                        WriteBuff.Writeu8(0);
                        WriteBuff.SendTcp(myClient.DataStream);
                        break;
                    }

                    //Success, put them in the room...
                    myClient.isInSession    = true;
                    myClient.CurrentSession = RoomId;

                    //...and then tell the player.
                    WriteBuff.SetPeek(0);
                    WriteBuff.Writeu8(myClient.HeaderId);
                    WriteBuff.Writeu8(Code.SessionJoin);
                    WriteBuff.Writeu8(1);
                    WriteBuff.SendTcp(myClient.DataStream);

                    break;
                }

                case (Code.SessionLeave):
                {
                    //Request to leave the room. Which room (To tell the players in that room he left)?
                    var RoomId = ReadBuff.Readu8();

                    //Cannot leave a room when you're not in one.
                    if (!myClient.isInSession)
                    {
                        WriteBuff.SetPeek(0);
                        WriteBuff.Writeu8(myClient.HeaderId);
                        WriteBuff.Writeu8(Code.SessionLeave);
                        WriteBuff.Writeu8(0);
                        WriteBuff.SendTcp(myClient.DataStream);
                        break;
                    }

                    //Success, take them out the room...
                    myClient.isInSession    = false;
                    myClient.CurrentSession = null;

                    //...and then tell the player.
                    WriteBuff.SetPeek(0);
                    WriteBuff.Writeu8(myClient.HeaderId);
                    WriteBuff.Writeu8(Code.SessionJoin);
                    WriteBuff.Writeu8(1);
                    WriteBuff.SendTcp(myClient.DataStream);

                    //As well as the other players in that room.
                    Session EveryoneElse = MainServer.SessionList.Find(e => e.GetID() == RoomId);
                    //Loop through all connected clients to see which is in the room.
                    {
                        foreach (KeyValuePair <long, TcpClientSocket> ClientSocket in TcpListenerSocket.ClientList)
                        {
                            if (ClientSocket.Value.CurrentSession == EveryoneElse)
                            {
                                WriteBuff.SetPeek(0);
                                WriteBuff.Writeu8(ClientSocket.Value.HeaderId);
                                WriteBuff.Writeu8(Code.PlayerLeave);
                                WriteBuff.Writeu8(1);
                                WriteBuff.SendTcp(ClientSocket.Value.DataStream);
                            }
                        }
                    }
                    //Then tell each of them that the player left.

                    break;
                }

                default: break;
                }

                // Back-up the read/peek position of the buffer and check for a secondary/merged packet.
                int myHeaderId = myClient.ReadBuffer.EndRead(false);
                myCheck = ( byte )((myHeaderId != -1) ? myHeaderId : ~myHeaderId);
            }
        }
예제 #12
0
        /// <summary>
        /// Starts handling the new client. If the client connects after MaxClients is exceeded, the client is disconnected.
        /// </summary>
        /// <param name="myClient">The client socket class that is being handled.</param>
        public async void ClientHandle(TcpClientSocket myClient)
        {
            if (ClientList.Count < MaxClients)
            {
                // Attempt to process the code, if not successful, throw an exception and disconnect the client.
                try {
                    // While the client is connected, process any data and respond accordingly.
                    while (myClient.Connected == true)
                    {
                        // Only process data if data is available(sent from the client to the server).

                        if (myClient.CurrentRoom != null)
                        {
                            Thread.Sleep(1);
                        }
                        else
                        {
                            Thread.Sleep(20);
                        }

                        // If a client-issued(not server-issued) disconnection has been detected close the client connection.
                        // Usually this is an unexpected disconnection, a proper disconnection should have a client send a message/packet requesting disconnection.
                        if (myClient.ClientHandle.Connected == false)
                        {
                            myClient.WriteBuffer.SetPeek(0);
                            myClient.WriteBuffer.WriteUByte(PacketHeader);
                            myClient.WriteBuffer.SendTcp(myClient.DataStream);
                            myClient.Connected = myClient.ClientHandle.Connected;
                        }

                        if (myClient.DataStream.DataAvailable == true)
                        {
                            myClient.DCTimer.Enabled  = false;
                            myClient.DCTimer.Interval = 30000;

                            // Clear the read and write buffers to respond to the newly received packet.
                            myClient.ReadBuffer.Reset();
                            myClient.WriteBuffer.Reset();

                            // Copy the received data from the client's network stream to the client's read buffer.
                            int PacketSize = myClient.ClientHandle.Available;
                            await myClient.DataStream.ReadAsync(myClient.ReadBuffer.Buffer, 0, PacketSize);

                            // Start reading the received data and respond accordingly.
                            TcpPackets.TcpPacketRead(myClient, this);
                        }
                        else
                        {
                            //So we didn't get any data. Set the timer for 30 seconds to force-remove the player unless they respond again.
                            myClient.DCTimer.Enabled = true;
                        }
                    }
                }
                catch (Exception e)
                {
                    myClient.Connected = false;

                    //if (myClient.UserImposedDisconnection == false)
                    {
                        CmdSystem.AddLog(myClient.Name + " has been disconnected.");
                        Console.WriteLine("===");
                        Console.WriteLine(e.Message);
                        Console.WriteLine(e.StackTrace);
                        Console.WriteLine("===");
                    }
                }
            }

            // If the client disconnects, run a method that happens upon client disconnection.

            /*
             *	NOTE: If a client disconnections by itself you can NOT use this to send messages back to the client.
             *	Even though you can't send a message back to the client, you can still do something else. Such as
             *	displaying a console output or sending a message to other clients that this client disconnected.
             */
            // You CAN send messages back to the client if the client is being disconnected by the server instead!
            // This is because the client is still connected to the server while the ClientDisconnect() method is run.
            // However, the client is disconnected AFTER the ClientDisconnect() method.

            if (myClient.CurrentRoom != null)
            {
                myClient.CurrentRoom.Remove(myClient);
            }

            TcpPackets.TcpDisconnect(myClient);

            // Remove the client from the client list when it disconnects.
            ClientList.Remove(myClient.SocketId);
            myClient.TcpClientClose();

            if (myClient.ListSlot != null)
            {
                myClient.ListSlot.GoOffline();
            }
        }
예제 #13
0
        public static void Main()
        {
            ClockTimer.RecordRunTime();

            Console.Clear();
            Console.WriteLine("    ====================================================    ");
            Console.WriteLine("    Welcome to the BBLegacy Dedicated Server [prototype]    ");
            Console.WriteLine();
            Console.WriteLine("     INIFile Management Code by S.T.A. snc (C)2009-2013     ");
            Console.WriteLine("    Networking System by FatalSleep from the GMCommunity    ");
            Console.WriteLine("    ====================================================    ");
            Console.WriteLine();

            //Fetch the External IP Address, if they're not using local.

            if (IsLocal)
            {
                TheIPAddress = "127.0.0.1";
            }
            else
            {
                Console.WriteLine("Fetching IP Address... ");
                TheIPAddress = getExternalIp();

                Console.WriteLine("     " + TheIPAddress + ", LAN " + getInternalIP());
            }

            Console.WriteLine("Loading player database...");
            new UpdateINI(3600000);
            MessageUpdate = new MessageUpdater(120000);
            Event         = new Automation();

            var tmp = 1;

            while (tmp <= SettingsFile.GetValue("Server Configuration", "NumberOfPlayers", 1))
            {
                PlayerListItem tmpp = new PlayerListItem();
                tmpp.ID   = SettingsFile.GetValue("PlayerListItem" + tmp, "ID", 0.00);
                tmpp.Name = SettingsFile.GetValue("PlayerListItem" + tmp, "Name", "{NULL}");
                tmpp.Tag  = (byte)SettingsFile.GetValue("PlayerListItem" + tmp, "Tag", 0);
                Console.WriteLine("    PL" + tmpp.ID + " " + tmpp.Name + " (" + tmpp.Tag + ")");
                tmp++;

                if (tmpp.Tag == 0)
                {
                    tmpp.Automate();
                }
            }

            Console.WriteLine("done.");

            myTcpSocket = new TcpListenerSocket(TheIPAddress, Port, MaxClients, ReadSize, WriteSize, Alignment, PacketHeader);

            myUdpSocket = new UdpServerSocket(Port, ReadSize, WriteSize, Alignment, PacketHeader);

            Console.WriteLine("UDP Connection Listener Established (" + TheIPAddress + " :: " + Port + ")");
            string Command = "";

            if (!CanCreateRooms)
            {
                Console.WriteLine("WARNING: Player creation of rooms is disabled. You MUST use room creation commands in order for them to play on your server!");
            }

            Thread.Sleep(2000);
            Console.WriteLine("You can now type 'help' for some commands.");
            Console.WriteLine();
            Console.WriteLine("    ====================================================    ");

            while (myTcpSocket.Status == true || myUdpSocket.Status == true)
            {
                try
                {
                    Command = Console.ReadLine();
                    CmdSystem.RunCmd(Command);
                }
                catch (Exception e)
                {
                    CmdSystem.AddLog("UNCAUGHT EXCEPTION: " + e.GetType() + " :: " + e.Message);
                    CmdSystem.AddLog("Stack Trace: ");
                    Console.WriteLine();
                    Console.WriteLine(e.StackTrace);
                    Console.WriteLine();
                }
            }
            ClockTimer.StopRunTime();
        }