Пример #1
0
        // _Host_Frame
        //
        //Runs all active servers
        static void InternalFrame(double time)
        {
            // keep the random time dependent
            Sys.Random();

            // decide the simulation time
            if (!FilterTime(time))
            {
                return;                 // don't run too fast, or packets will flood out
            }
            // get new key events
            Sys.SendKeyEvents();

            // allow mice or other external controllers to add commands
            Input.Commands();

            // process console commands
            Cbuf.Execute();

            Net.Poll();

            // if running the server locally, make intentions now
            if (Server.sv.active)
            {
                Client.SendCmd();
            }

            //-------------------
            //
            // server operations
            //
            //-------------------

            // check for commands typed to the host
            GetConsoleCommands();

            if (Server.sv.active)
            {
                ServerFrame();
            }

            //-------------------
            //
            // client operations
            //
            //-------------------

            // if running the server remotely, send intentions now after
            // the incoming messages have been read
            if (!Server.sv.active)
            {
                Client.SendCmd();
            }

            _Time += FrameTime;

            // fetch results from server
            if (Client.cls.state == cactive_t.ca_connected)
            {
                Client.ReadFromServer();
            }

            // update video
            if (_Speeds.Value != 0)
            {
                _Time1 = Sys.GetFloatTime();
            }

            Scr.UpdateScreen();

            if (_Speeds.Value != 0)
            {
                _Time2 = Sys.GetFloatTime();
            }

            // update audio
            if (Client.cls.signon == Client.SIGNONS)
            {
                Sound.Update(ref Render.Origin, ref Render.ViewPn, ref Render.ViewRight, ref Render.ViewUp);
                Client.DecayLights();
            }
            else
            {
                Sound.Update(ref Common.ZeroVector, ref Common.ZeroVector, ref Common.ZeroVector, ref Common.ZeroVector);
            }

            CDAudio.Update();

            if (_Speeds.Value != 0)
            {
                int pass1 = (int)((_Time1 - _Time3) * 1000);
                _Time3 = Sys.GetFloatTime();
                int pass2 = (int)((_Time2 - _Time1) * 1000);
                int pass3 = (int)((_Time3 - _Time2) * 1000);
                Con.Print("{0,3} tot {1,3} server {2,3} gfx {3,3} snd\n", pass1 + pass2 + pass3, pass1, pass2, pass3);
            }

            _FrameCount++;
        }
Пример #2
0
 /// <summary>
 /// SCR_EndLoadingPlaque
 /// </summary>
 public static void EndLoadingPlaque()
 {
     Scr.IsDisabledForLoading = false;
     Scr.FullUpdate           = 0;
     Con.ClearNotify();
 }
Пример #3
0
        /// <summary>
        /// Host_ShutdownServer
        /// This only happens at the end of a game, not between levels
        /// </summary>
        public static void ShutdownServer(bool crash)
        {
            if (!Server.IsActive)
            {
                return;
            }

            Server.sv.active = false;

            // stop all client sounds immediately
            if (Client.cls.state == cactive_t.ca_connected)
            {
                Client.Disconnect();
            }

            // flush any pending messages - like the score!!!
            double start = Sys.GetFloatTime();
            int    count;

            do
            {
                count = 0;
                for (int i = 0; i < Server.svs.maxclients; i++)
                {
                    HostClient = Server.svs.clients[i];
                    if (HostClient.active && !HostClient.message.IsEmpty)
                    {
                        if (Net.CanSendMessage(HostClient.netconnection))
                        {
                            Net.SendMessage(HostClient.netconnection, HostClient.message);
                            HostClient.message.Clear();
                        }
                        else
                        {
                            Net.GetMessage(HostClient.netconnection);
                            count++;
                        }
                    }
                }
                if ((Sys.GetFloatTime() - start) > 3.0)
                {
                    break;
                }
            }while (count > 0);

            // make sure all the clients know we're disconnecting
            MsgWriter writer = new MsgWriter(4);

            writer.WriteByte(Protocol.svc_disconnect);
            count = Net.SendToAll(writer, 5);
            if (count != 0)
            {
                Con.Print("Host_ShutdownServer: NET_SendToAll failed for {0} clients\n", count);
            }

            for (int i = 0; i < Server.svs.maxclients; i++)
            {
                HostClient = Server.svs.clients[i];
                if (HostClient.active)
                {
                    Server.DropClient(crash);
                }
            }

            //
            // clear structures
            //
            Server.sv.Clear();
            for (int i = 0; i < Server.svs.clients.Length; i++)
            {
                Server.svs.clients[i].Clear();
            }
        }
Пример #4
0
        /// <summary>
        /// UDP_Init
        /// </summary>
        public bool Init()
        {
            _IsInitialized = false;

            if (Common.HasParam("-noudp"))
            {
                return(false);
            }

            // determine my name
            string hostName;

            try
            {
                hostName = Dns.GetHostName();
            }
            catch (SocketException se)
            {
                Con.DPrint("Cannot get host name: {0}\n", se.Message);
                return(false);
            }

            // if the quake hostname isn't set, set it to the machine name
            if (Net.HostName == "UNNAMED")
            {
                IPAddress addr;
                if (!IPAddress.TryParse(hostName, out addr))
                {
                    int i = hostName.IndexOf('.');
                    if (i != -1)
                    {
                        hostName = hostName.Substring(0, i);
                    }
                }
                Cvar.Set("hostname", hostName);
            }

            int i2 = Common.CheckParm("-ip");

            if (i2 > 0)
            {
                if (i2 < Common.Argc - 1)
                {
                    string ipaddr = Common.Argv(i2 + 1);
                    if (!IPAddress.TryParse(ipaddr, out _MyAddress))
                    {
                        Sys.Error("{0} is not a valid IP address!", ipaddr);
                    }
                    Net.MyTcpIpAddress = ipaddr;
                }
                else
                {
                    Sys.Error("Net.Init: you must specify an IP address after -ip");
                }
            }
            else
            {
                _MyAddress         = IPAddress.Any;
                Net.MyTcpIpAddress = "INADDR_ANY";
            }

            _ControlSocket = OpenSocket(0);
            if (_ControlSocket == null)
            {
                Con.Print("TCP/IP: Unable to open control socket\n");
                return(false);
            }

            _BroadcastAddress = new IPEndPoint(IPAddress.Broadcast, Net.HostPort);

            _IsInitialized = true;
            Con.Print("TCP/IP Initialized\n");
            return(true);
        }
Пример #5
0
        // void SCR_UpdateScreen (void);
        // This is called every frame, and can also be called explicitly to flush
        // text to the screen.
        //
        // WARNING: be very careful calling this from elsewhere, because the refresh
        // needs almost the entire 256k of stack space!
        public static void UpdateScreen()
        {
            if (BlockDrawing || !_IsInitialized || _InUpdate)
            {
                return;
            }

            _InUpdate = true;
            try
            {
                if (MainForm.Instance != null)
                {
                    if ((MainForm.Instance.VSync == VSyncMode.On) != Vid.Wait)
                    {
                        MainForm.Instance.VSync = (Vid.Wait ? VSyncMode.On : VSyncMode.Off);
                    }
                }

                _VidDef.numpages = 2 + (int)_glTripleBuffer.Value;

                CopyTop         = false;
                _CopyEverything = false;

                if (IsDisabledForLoading)
                {
                    if ((Host.RealTime - _DisabledTime) > 60)
                    {
                        IsDisabledForLoading = false;
                        Con.Print("Load failed.\n");
                    }
                    else
                    {
                        return;
                    }
                }

                if (!Con.IsInitialized)
                {
                    return;     // not initialized yet
                }
                BeginRendering();

                //
                // determine size of refresh window
                //
                if (_OldFov != _Fov.Value)
                {
                    _OldFov = _Fov.Value;
                    _VidDef.recalc_refdef = true;
                }

                if (_OldScreenSize != _ViewSize.Value)
                {
                    _OldScreenSize        = _ViewSize.Value;
                    _VidDef.recalc_refdef = true;
                }

                if (_VidDef.recalc_refdef)
                {
                    CalcRefdef();
                }

                //
                // do 3D refresh drawing, and then update the screen
                //
                SetUpToDrawConsole();

                View.RenderView();

                Set2D();

                //
                // draw any areas not covered by the refresh
                //
                Scr.TileClear();

                if (_DrawDialog)
                {
                    Sbar.Draw();
                    Drawer.FadeScreen();
                    DrawNotifyString();
                    _CopyEverything = true;
                }
                else if (_DrawLoading)
                {
                    DrawLoading();
                    Sbar.Draw();
                }
                else if (Client.cl.intermission == 1 && Key.Destination == keydest_t.key_game)
                {
                    Sbar.IntermissionOverlay();
                }
                else if (Client.cl.intermission == 2 && Key.Destination == keydest_t.key_game)
                {
                    Sbar.FinaleOverlay();
                    CheckDrawCenterString();
                }
                else
                {
                    if (View.Crosshair > 0)
                    {
                        Drawer.DrawCharacter(_VRect.x + _VRect.width / 2, _VRect.y + _VRect.height / 2, '+');
                    }

                    //Drawer.DrawString(8, vid.height - Sbar.SBAR_HEIGHT, $"{Math.Round(1.0 / Host.FrameTime)}fps");
                    ;

                    DrawRam();
                    DrawNet();
                    DrawTurtle();
                    DrawPause();
                    CheckDrawCenterString();
                    Sbar.Draw();
                    DrawConsole();
                    Menu.Draw();
                }

                View.UpdatePalette();
                EndRendering();
            }
            finally
            {
                _InUpdate = false;
            }
        }
Пример #6
0
        /// <summary>
        /// R_SplitEntityOnNode
        /// </summary>
        static void SplitEntityOnNode(mnodebase_t node)
        {
            if (node.contents == Contents.CONTENTS_SOLID)
                return;

            // add an efrag if the node is a leaf
            if (node.contents < 0)
            {
                if (_EfragTopNode == null)
                    _EfragTopNode = node as mnode_t;

                mleaf_t leaf = (mleaf_t)(object)node;

                // grab an efrag off the free list
                efrag_t ef = Client.cl.free_efrags;
                if (ef == null)
                {
                    Con.Print("Too many efrags!\n");
                    return;	// no free fragments...
                }
                Client.cl.free_efrags = Client.cl.free_efrags.entnext;

                ef.entity = _AddEnt;

                // add the entity link
                // *lastlink = ef;
                if (_LastObj is entity_t)
                {
                    ((entity_t)_LastObj).efrag = ef;
                }
                else
                {
                    ((efrag_t)_LastObj).entnext = ef;
                }
                _LastObj = ef; // lastlink = &ef->entnext;
                ef.entnext = null;

                // set the leaf links
                ef.leaf = leaf;
                ef.leafnext = leaf.efrags;
                leaf.efrags = ef;

                return;
            }

            // NODE_MIXED
            mnode_t n = node as mnode_t;
            if (n == null)
                return;
            
            mplane_t splitplane = n.plane;
            int sides = Mathlib.BoxOnPlaneSide(ref _EMins, ref _EMaxs, splitplane);

            if (sides == 3)
            {
                // split on this plane
                // if this is the first splitter of this bmodel, remember it
                if (_EfragTopNode == null)
                    _EfragTopNode = n;
            }

            // recurse down the contacted sides
            if ((sides & 1) != 0)
                SplitEntityOnNode(n.children[0]);

            if ((sides & 2) != 0)
                SplitEntityOnNode(n.children[1]);
        }
Пример #7
0
        /// <summary>
        /// SV_ReadClientMessage
        /// Returns false if the client should be killed
        /// </summary>
        static bool ReadClientMessage()
        {
            while (true)
            {
                int ret = Net.GetMessage(Host.HostClient.netconnection);
                if (ret == -1)
                {
                    Con.DPrint("SV_ReadClientMessage: NET_GetMessage failed\n");
                    return(false);
                }
                if (ret == 0)
                {
                    return(true);
                }

                Net.Reader.Reset();

                bool flag = true;
                while (flag)
                {
                    if (!Host.HostClient.active)
                    {
                        return(false);   // a command caused an error
                    }
                    if (Net.Reader.IsBadRead)
                    {
                        Con.DPrint("SV_ReadClientMessage: badread\n");
                        return(false);
                    }

                    int cmd = Net.Reader.ReadChar();
                    switch (cmd)
                    {
                    case -1:
                        flag = false;     // end of message
                        ret  = 1;
                        break;

                    case Protocol.clc_nop:
                        break;

                    case Protocol.clc_stringcmd:
                        string s = Net.Reader.ReadString();
                        if (Host.HostClient.privileged)
                        {
                            ret = 2;
                        }
                        else
                        {
                            ret = 0;
                        }
                        if (Common.SameText(s, "status", 6))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "god", 3))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "notarget", 8))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "fly", 3))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "name", 4))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "noclip", 6))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "say", 3))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "say_team", 8))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "tell", 4))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "color", 5))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "kill", 4))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "pause", 5))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "spawn", 5))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "begin", 5))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "prespawn", 8))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "kick", 4))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "ping", 4))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "give", 4))
                        {
                            ret = 1;
                        }
                        else if (Common.SameText(s, "ban", 3))
                        {
                            ret = 1;
                        }
                        if (ret == 2)
                        {
                            Cbuf.InsertText(s);
                        }
                        else if (ret == 1)
                        {
                            Cmd.ExecuteString(s, cmd_source_t.src_client);
                        }
                        else
                        {
                            Con.DPrint("{0} tried to {1}\n", Host.HostClient.name, s);
                        }
                        break;

                    case Protocol.clc_disconnect:
                        return(false);

                    case Protocol.clc_move:
                        ReadClientMove(ref Host.HostClient.cmd);
                        break;

                    default:
                        Con.DPrint("SV_ReadClientMessage: unknown command char\n");
                        return(false);
                    }
                }

                if (ret != 1)
                {
                    break;
                }
            }

            return(true);
        }
Пример #8
0
        // Key_Event (int key, qboolean down)
        //
        // Called by the system between frames for both key up and key down events
        // Should NOT be called during an interrupt!
        public static void Event(int key, bool down)
        {
            _KeyDown[key] = down;

            if (!down)
            {
                _Repeats[key] = 0;
            }

            _LastPress = key;
            KeyCount++;
            if (KeyCount <= 0)
            {
                return;                 // just catching keys for Con_NotifyBox
            }
            // update auto-repeat status
            if (down)
            {
                _Repeats[key]++;
                if (key != K_BACKSPACE && key != K_PAUSE && key != K_PGUP && key != K_PGDN && _Repeats[key] > 1)
                {
                    return;             // ignore most autorepeats
                }

                if (key >= 200 && String.IsNullOrEmpty(_Bindings[key]))
                {
                    Con.Print("{0} is unbound, hit F4 to set.\n", KeynumToString(key));
                }
            }

            if (key == K_SHIFT)
            {
                _ShiftDown = down;
            }

            //
            // handle escape specialy, so the user can never unbind it
            //
            if (key == K_ESCAPE)
            {
                if (!down)
                {
                    return;
                }

                switch (_KeyDest)
                {
                case keydest_t.key_message:
                    KeyMessage(key);
                    break;

                case keydest_t.key_menu:
                    Menu.KeyDown(key);
                    break;

                case keydest_t.key_game:
                case keydest_t.key_console:
                    Menu.ToggleMenu_f();
                    break;

                default:
                    Sys.Error("Bad key_dest");
                    break;
                }
                return;
            }

            //
            // key up events only generate commands if the game key binding is
            // a button command (leading + sign).  These will occur even in console mode,
            // to keep the character from continuing an action started before a console
            // switch.  Button commands include the keynum as a parameter, so multiple
            // downs can be matched with ups
            //
            if (!down)
            {
                string kb = _Bindings[key];
                if (!String.IsNullOrEmpty(kb) && kb.StartsWith("+"))
                {
                    Cbuf.AddText(String.Format("-{0} {1}\n", kb.Substring(1), key));
                }
                if (_KeyShift[key] != key)
                {
                    kb = _Bindings[_KeyShift[key]];
                    if (!String.IsNullOrEmpty(kb) && kb.StartsWith("+"))
                    {
                        Cbuf.AddText(String.Format("-{0} {1}\n", kb.Substring(1), key));
                    }
                }
                return;
            }

            //
            // during demo playback, most keys bring up the main menu
            //
            if (Client.cls.demoplayback && down && _ConsoleKeys[key] && _KeyDest == keydest_t.key_game)
            {
                Menu.ToggleMenu_f();
                return;
            }

            //
            // if not a consolekey, send to the interpreter no matter what mode is
            //
            if ((_KeyDest == keydest_t.key_menu && _MenuBound[key]) ||
                (_KeyDest == keydest_t.key_console && !_ConsoleKeys[key]) ||
                (_KeyDest == keydest_t.key_game && (!Con.ForcedUp || !_ConsoleKeys[key])))
            {
                string kb = _Bindings[key];
                if (!String.IsNullOrEmpty(kb))
                {
                    if (kb.StartsWith("+"))
                    {
                        // button commands add keynum as a parm
                        Cbuf.AddText(String.Format("{0} {1}\n", kb, key));
                    }
                    else
                    {
                        Cbuf.AddText(kb);
                        Cbuf.AddText("\n");
                    }
                }
                return;
            }

            if (!down)
            {
                return;                 // other systems only care about key down events
            }
            if (_ShiftDown)
            {
                key = _KeyShift[key];
            }

            switch (_KeyDest)
            {
            case keydest_t.key_message:
                KeyMessage(key);
                break;

            case keydest_t.key_menu:
                Menu.KeyDown(key);
                break;

            case keydest_t.key_game:
            case keydest_t.key_console:
                KeyConsole(key);
                break;

            default:
                Sys.Error("Bad key_dest");
                break;
            }
        }
Пример #9
0
        /// <summary>
        /// Key_Console
        /// Interactive line editing and console scrollback
        /// </summary>
        static void KeyConsole(int key)
        {
            if (key == K_ENTER)
            {
                string line = new String(_Lines[_EditLine]).TrimEnd('\0', ' ');
                string cmd  = line.Substring(1);
                Cbuf.AddText(cmd);      // skip the >
                Cbuf.AddText("\n");
                Con.Print("{0}\n", line);
                _EditLine            = (_EditLine + 1) & 31;
                _HistoryLine         = _EditLine;
                _Lines[_EditLine][0] = ']';
                Key.LinePos          = 1;
                if (Client.cls.state == cactive_t.ca_disconnected)
                {
                    Scr.UpdateScreen(); // force an update, because the command
                }
                // may take some time
                return;
            }

            if (key == K_TAB)
            {
                // command completion
                string   txt   = new String(_Lines[_EditLine], 1, MAXCMDLINE - 1).TrimEnd('\0', ' ');
                string[] cmds  = Cmd.Complete(txt);
                string[] vars  = Cvar.CompleteName(txt);
                string   match = null;
                if (cmds != null)
                {
                    if (cmds.Length > 1 || vars != null)
                    {
                        Con.Print("\nCommands:\n");
                        foreach (string s in cmds)
                        {
                            Con.Print("  {0}\n", s);
                        }
                    }
                    else
                    {
                        match = cmds[0];
                    }
                }
                if (vars != null)
                {
                    if (vars.Length > 1 || cmds != null)
                    {
                        Con.Print("\nVariables:\n");
                        foreach (string s in vars)
                        {
                            Con.Print("  {0}\n", s);
                        }
                    }
                    else if (match == null)
                    {
                        match = vars[0];
                    }
                }
                if (!String.IsNullOrEmpty(match))
                {
                    int len = Math.Min(match.Length, MAXCMDLINE - 3);
                    for (int i = 0; i < len; i++)
                    {
                        _Lines[_EditLine][i + 1] = match[i];
                    }
                    Key.LinePos = len + 1;
                    _Lines[_EditLine][Key.LinePos] = ' ';
                    Key.LinePos++;
                    _Lines[_EditLine][Key.LinePos] = '\0';
                    return;
                }
            }

            if (key == K_BACKSPACE || key == K_LEFTARROW)
            {
                if (Key.LinePos > 1)
                {
                    Key.LinePos--;
                }
                return;
            }

            if (key == K_UPARROW)
            {
                do
                {
                    _HistoryLine = (_HistoryLine - 1) & 31;
                } while (_HistoryLine != _EditLine && (_Lines[_HistoryLine][1] == 0));
                if (_HistoryLine == _EditLine)
                {
                    _HistoryLine = (_EditLine + 1) & 31;
                }
                Array.Copy(_Lines[_HistoryLine], _Lines[_EditLine], MAXCMDLINE);
                Key.LinePos = 0;
                while (_Lines[_EditLine][Key.LinePos] != '\0' && Key.LinePos < MAXCMDLINE)
                {
                    Key.LinePos++;
                }
                return;
            }

            if (key == K_DOWNARROW)
            {
                if (_HistoryLine == _EditLine)
                {
                    return;
                }
                do
                {
                    _HistoryLine = (_HistoryLine + 1) & 31;
                }while (_HistoryLine != _EditLine && (_Lines[_HistoryLine][1] == '\0'));
                if (_HistoryLine == _EditLine)
                {
                    _Lines[_EditLine][0] = ']';
                    Key.LinePos          = 1;
                }
                else
                {
                    Array.Copy(_Lines[_HistoryLine], _Lines[_EditLine], MAXCMDLINE);
                    Key.LinePos = 0;
                    while (_Lines[_EditLine][Key.LinePos] != '\0' && Key.LinePos < MAXCMDLINE)
                    {
                        Key.LinePos++;
                    }
                }
                return;
            }

            if (key == K_PGUP || key == K_MWHEELUP)
            {
                Con.BackScroll += 2;
                if (Con.BackScroll > Con.TotalLines - (Scr.vid.height >> 3) - 1)
                {
                    Con.BackScroll = Con.TotalLines - (Scr.vid.height >> 3) - 1;
                }
                return;
            }

            if (key == K_PGDN || key == K_MWHEELDOWN)
            {
                Con.BackScroll -= 2;
                if (Con.BackScroll < 0)
                {
                    Con.BackScroll = 0;
                }
                return;
            }

            if (key == K_HOME)
            {
                Con.BackScroll = Con.TotalLines - (Scr.vid.height >> 3) - 1;
                return;
            }

            if (key == K_END)
            {
                Con.BackScroll = 0;
                return;
            }

            if (key < 32 || key > 127)
            {
                return; // non printable
            }
            if (Key.LinePos < MAXCMDLINE - 1)
            {
                _Lines[_EditLine][Key.LinePos] = (char)key;
                Key.LinePos++;
                _Lines[_EditLine][Key.LinePos] = '\0';
            }
        }
Пример #10
0
        /// <summary>
        /// Host_Status_f
        /// </summary>
        static void Status_f()
        {
            bool flag = true;

            if (Cmd.Source == cmd_source_t.src_command)
            {
                if (!Server.sv.active)
                {
                    Cmd.ForwardToServer();
                    return;
                }
            }
            else
            {
                flag = false;
            }

            StringBuilder sb = new StringBuilder(256);

            sb.Append(String.Format("host:    {0}\n", Cvar.GetString("hostname")));
            sb.Append(String.Format("version: {0:F2}\n", QDef.VERSION));
            if (Net.TcpIpAvailable)
            {
                sb.Append("tcp/ip:  ");
                sb.Append(Net.MyTcpIpAddress);
                sb.Append('\n');
            }

            sb.Append("map:     ");
            sb.Append(Server.sv.name);
            sb.Append('\n');
            sb.Append(String.Format("players: {0} active ({1} max)\n\n", Net.ActiveConnections, Server.svs.maxclients));
            for (int j = 0; j < Server.svs.maxclients; j++)
            {
                client_t client = Server.svs.clients[j];
                if (!client.active)
                {
                    continue;
                }

                int seconds = (int)(Net.Time - client.netconnection.connecttime);
                int hours, minutes = seconds / 60;
                if (minutes > 0)
                {
                    seconds -= (minutes * 60);
                    hours    = minutes / 60;
                    if (hours > 0)
                    {
                        minutes -= (hours * 60);
                    }
                }
                else
                {
                    hours = 0;
                }
                sb.Append(String.Format("#{0,-2} {1,-16}  {2}  {2}:{4,2}:{5,2}",
                                        j + 1, client.name, (int)client.edict.v.frags, hours, minutes, seconds));
                sb.Append("   ");
                sb.Append(client.netconnection.address);
                sb.Append('\n');
            }

            if (flag)
            {
                Con.Print(sb.ToString());
            }
            else
            {
                Server.ClientPrint(sb.ToString());
            }
        }
Пример #11
0
 // Host_Version_f
 static void Version_f()
 {
     Con.Print("Version {0}\n", QDef.VERSION);
     Con.Print("Exe hash code: {0}\n", System.Reflection.Assembly.GetExecutingAssembly().GetHashCode());
 }
Пример #12
0
        /// <summary>
        /// Host_Loadgame_f
        /// </summary>
        static void Loadgame_f()
        {
            if (Cmd.Source != cmd_source_t.src_command)
            {
                return;
            }

            if (Cmd.Argc != 2)
            {
                Con.Print("load <savename> : load a game\n");
                return;
            }

            Client.cls.demonum = -1;            // stop demo loop in case this fails

            string name = Path.ChangeExtension(Path.Combine(Common.GameDir, Cmd.Argv(1)), ".sav");

            // we can't call SCR_BeginLoadingPlaque, because too much stack space has
            // been used.  The menu calls it before stuffing loadgame command
            //	SCR_BeginLoadingPlaque ();

            Con.Print("Loading game from {0}...\n", name);
            FileStream fs = Sys.FileOpenRead(name);

            if (fs == null)
            {
                Con.Print("ERROR: couldn't open.\n");
                return;
            }

            using (StreamReader reader = new StreamReader(fs, Encoding.ASCII))
            {
                string line    = reader.ReadLine();
                int    version = Common.atoi(line);
                if (version != SAVEGAME_VERSION)
                {
                    Con.Print("Savegame is version {0}, not {1}\n", version, SAVEGAME_VERSION);
                    return;
                }
                line = reader.ReadLine();

                float[] spawn_parms = new float[Server.NUM_SPAWN_PARMS];
                for (int i = 0; i < spawn_parms.Length; i++)
                {
                    line           = reader.ReadLine();
                    spawn_parms[i] = Common.atof(line);
                }
                // this silliness is so we can load 1.06 save files, which have float skill values
                line = reader.ReadLine();
                float tfloat = Common.atof(line);
                Host.CurrentSkill = (int)(tfloat + 0.1);
                Cvar.Set("skill", (float)Host.CurrentSkill);

                string mapname = reader.ReadLine();
                line = reader.ReadLine();
                float time = Common.atof(line);

                Client.Disconnect_f();
                Server.SpawnServer(mapname);

                if (!Server.sv.active)
                {
                    Con.Print("Couldn't load map\n");
                    return;
                }
                Server.sv.paused   = true;              // pause until all clients connect
                Server.sv.loadgame = true;

                // load the light styles

                for (int i = 0; i < QDef.MAX_LIGHTSTYLES; i++)
                {
                    line = reader.ReadLine();
                    Server.sv.lightstyles[i] = line;
                }

                // load the edicts out of the savegame file
                int           entnum = -1;      // -1 is the globals
                StringBuilder sb     = new StringBuilder(32768);
                while (!reader.EndOfStream)
                {
                    line = reader.ReadLine();
                    if (line == null)
                    {
                        Sys.Error("EOF without closing brace");
                    }

                    sb.AppendLine(line);
                    int idx = line.IndexOf('}');
                    if (idx != -1)
                    {
                        int    length = 1 + sb.Length - (line.Length - idx);
                        string data   = Common.Parse(sb.ToString(0, length));
                        if (String.IsNullOrEmpty(Common.Token))
                        {
                            break; // end of file
                        }
                        if (Common.Token != "{")
                        {
                            Sys.Error("First token isn't a brace");
                        }

                        if (entnum == -1)
                        {
                            // parse the global vars
                            Progs.ParseGlobals(data);
                        }
                        else
                        {
                            // parse an edict
                            edict_t ent = Server.EdictNum(entnum);
                            ent.Clear();
                            Progs.ParseEdict(data, ent);

                            // link it into the bsp tree
                            if (!ent.free)
                            {
                                Server.LinkEdict(ent, false);
                            }
                        }

                        entnum++;
                        sb.Remove(0, length);
                    }
                }

                Server.sv.num_edicts = entnum;
                Server.sv.time       = time;

                for (int i = 0; i < Server.NUM_SPAWN_PARMS; i++)
                {
                    Server.svs.clients[0].spawn_parms[i] = spawn_parms[i];
                }
            }

            if (Client.cls.state != cactive_t.ca_dedicated)
            {
                Client.EstablishConnection("local");
                Reconnect_f();
            }
        }
Пример #13
0
        /// <summary>
        /// Host_Savegame_f
        /// </summary>
        static void Savegame_f()
        {
            if (Cmd.Source != cmd_source_t.src_command)
            {
                return;
            }

            if (!Server.sv.active)
            {
                Con.Print("Not playing a local game.\n");
                return;
            }

            if (Client.cl.intermission != 0)
            {
                Con.Print("Can't save in intermission.\n");
                return;
            }

            if (Server.svs.maxclients != 1)
            {
                Con.Print("Can't save multiplayer games.\n");
                return;
            }

            if (Cmd.Argc != 2)
            {
                Con.Print("save <savename> : save a game\n");
                return;
            }

            if (Cmd.Argv(1).Contains(".."))
            {
                Con.Print("Relative pathnames are not allowed.\n");
                return;
            }

            for (int i = 0; i < Server.svs.maxclients; i++)
            {
                if (Server.svs.clients[i].active && (Server.svs.clients[i].edict.v.health <= 0))
                {
                    Con.Print("Can't savegame with a dead player\n");
                    return;
                }
            }

            string name = Path.ChangeExtension(Path.Combine(Common.GameDir, Cmd.Argv(1)), ".sav");

            Con.Print("Saving game to {0}...\n", name);
            FileStream fs = Sys.FileOpenWrite(name, true);

            if (fs == null)
            {
                Con.Print("ERROR: couldn't open.\n");
                return;
            }
            using (StreamWriter writer = new StreamWriter(fs, Encoding.ASCII))
            {
                writer.WriteLine(SAVEGAME_VERSION);
                writer.WriteLine(SavegameComment());

                for (int i = 0; i < Server.NUM_SPAWN_PARMS; i++)
                {
                    writer.WriteLine(Server.svs.clients[0].spawn_parms[i].ToString("F6",
                                                                                   CultureInfo.InvariantCulture.NumberFormat));
                }

                writer.WriteLine(Host.CurrentSkill);
                writer.WriteLine(Server.sv.name);
                writer.WriteLine(Server.sv.time.ToString("F6",
                                                         CultureInfo.InvariantCulture.NumberFormat));

                // write the light styles

                for (int i = 0; i < QDef.MAX_LIGHTSTYLES; i++)
                {
                    if (!String.IsNullOrEmpty(Server.sv.lightstyles[i]))
                    {
                        writer.WriteLine(Server.sv.lightstyles[i]);
                    }
                    else
                    {
                        writer.WriteLine("m");
                    }
                }

                Progs.WriteGlobals(writer);
                for (int i = 0; i < Server.sv.num_edicts; i++)
                {
                    Progs.WriteEdict(writer, Server.EdictNum(i));
                    writer.Flush();
                }
            }
            Con.Print("done.\n");
        }
Пример #14
0
        /// <summary>
        /// Host_Spawn_f
        /// </summary>
        static void Spawn_f()
        {
            if (Cmd.Source == cmd_source_t.src_command)
            {
                Con.Print("spawn is not valid from the console\n");
                return;
            }

            if (Host.HostClient.spawned)
            {
                Con.Print("Spawn not valid -- allready spawned\n");
                return;
            }

            edict_t ent;

            // run the entrance script
            if (Server.sv.loadgame)
            {
                // loaded games are fully inited allready
                // if this is the last client to be connected, unpause
                Server.sv.paused = false;
            }
            else
            {
                // set up the edict
                ent = Host.HostClient.edict;

                ent.Clear(); //memset(&ent.v, 0, progs.entityfields * 4);
                ent.v.colormap = Server.NumForEdict(ent);
                ent.v.team     = (Host.HostClient.colors & 15) + 1;
                ent.v.netname  = Progs.NewString(Host.HostClient.name);

                // copy spawn parms out of the client_t
                Progs.GlobalStruct.SetParams(Host.HostClient.spawn_parms);

                // call the spawn function

                Progs.GlobalStruct.time = (float)Server.sv.time;
                Progs.GlobalStruct.self = Server.EdictToProg(Server.Player);
                Progs.Execute(Progs.GlobalStruct.ClientConnect);

                if ((Sys.GetFloatTime() - Host.HostClient.netconnection.connecttime) <= Server.sv.time)
                {
                    Con.DPrint("{0} entered the game\n", Host.HostClient.name);
                }

                Progs.Execute(Progs.GlobalStruct.PutClientInServer);
            }


            // send all current names, colors, and frag counts
            MsgWriter msg = Host.HostClient.message;

            msg.Clear();

            // send time of update
            msg.WriteByte(Protocol.svc_time);
            msg.WriteFloat((float)Server.sv.time);

            for (int i = 0; i < Server.svs.maxclients; i++)
            {
                client_t client = Server.svs.clients[i];
                msg.WriteByte(Protocol.svc_updatename);
                msg.WriteByte(i);
                msg.WriteString(client.name);
                msg.WriteByte(Protocol.svc_updatefrags);
                msg.WriteByte(i);
                msg.WriteShort(client.old_frags);
                msg.WriteByte(Protocol.svc_updatecolors);
                msg.WriteByte(i);
                msg.WriteByte(client.colors);
            }

            // send all current light styles
            for (int i = 0; i < QDef.MAX_LIGHTSTYLES; i++)
            {
                msg.WriteByte(Protocol.svc_lightstyle);
                msg.WriteByte((char)i);
                msg.WriteString(Server.sv.lightstyles[i]);
            }

            //
            // send some stats
            //
            msg.WriteByte(Protocol.svc_updatestat);
            msg.WriteByte(QStats.STAT_TOTALSECRETS);
            msg.WriteLong((int)Progs.GlobalStruct.total_secrets);

            msg.WriteByte(Protocol.svc_updatestat);
            msg.WriteByte(QStats.STAT_TOTALMONSTERS);
            msg.WriteLong((int)Progs.GlobalStruct.total_monsters);

            msg.WriteByte(Protocol.svc_updatestat);
            msg.WriteByte(QStats.STAT_SECRETS);
            msg.WriteLong((int)Progs.GlobalStruct.found_secrets);

            msg.WriteByte(Protocol.svc_updatestat);
            msg.WriteByte(QStats.STAT_MONSTERS);
            msg.WriteLong((int)Progs.GlobalStruct.killed_monsters);


            //
            // send a fixangle
            // Never send a roll angle, because savegames can catch the server
            // in a state where it is expecting the client to correct the angle
            // and it won't happen if the game was just loaded, so you wind up
            // with a permanent head tilt
            ent = Server.EdictNum(1 + Host.ClientNum);
            msg.WriteByte(Protocol.svc_setangle);
            msg.WriteAngle(ent.v.angles.x);
            msg.WriteAngle(ent.v.angles.y);
            msg.WriteAngle(0);

            Server.WriteClientDataToMessage(Server.Player, Host.HostClient.message);

            msg.WriteByte(Protocol.svc_signonnum);
            msg.WriteByte(3);
            Host.HostClient.sendsignon = true;
        }