⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sv_main.java

📁 JAKE2用JAVA写的queck2的3D游戏开发引擎
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
            }        }        // find a client slot        //newcl = null;        int index = -1;        for (i = 0; i < SV_MAIN.maxclients.value; i++) {            cl = SV_INIT.svs.clients[i];            if (cl.state == Defines.cs_free) {                index = i;                break;            }        }        if (index == -1) {            Netchan.OutOfBandPrint(Defines.NS_SERVER, adr,                    "print\nServer is full.\n");            Com.DPrintf("Rejected a connection.\n");            return;        }        gotnewcl(index, challenge, userinfo, adr, qport);    }    /**     * Initializes player structures after successfull connection.     */    public static void gotnewcl(int i, int challenge, String userinfo,            netadr_t adr, int qport) {        // build a new connection        // accept the new client        // this is the only place a client_t is ever initialized        SV_MAIN.sv_client = SV_INIT.svs.clients[i];                int edictnum = i + 1;                edict_t ent = GameBase.g_edicts[edictnum];        SV_INIT.svs.clients[i].edict = ent;                // save challenge for checksumming        SV_INIT.svs.clients[i].challenge = challenge;                        // get the game a chance to reject this connection or modify the        // userinfo        if (!(PlayerClient.ClientConnect(ent, userinfo))) {            if (Info.Info_ValueForKey(userinfo, "rejmsg") != null)                Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\n"                        + Info.Info_ValueForKey(userinfo, "rejmsg")                        + "\nConnection refused.\n");            else                Netchan.OutOfBandPrint(Defines.NS_SERVER, adr,                        "print\nConnection refused.\n");            Com.DPrintf("Game rejected a connection.\n");            return;        }        // parse some info from the info strings        SV_INIT.svs.clients[i].userinfo = userinfo;        SV_UserinfoChanged(SV_INIT.svs.clients[i]);        // send the connect packet to the client        Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "client_connect");        Netchan.Setup(Defines.NS_SERVER, SV_INIT.svs.clients[i].netchan, adr, qport);        SV_INIT.svs.clients[i].state = Defines.cs_connected;        SZ.Init(SV_INIT.svs.clients[i].datagram,                SV_INIT.svs.clients[i].datagram_buf,                SV_INIT.svs.clients[i].datagram_buf.length);                SV_INIT.svs.clients[i].datagram.allowoverflow = true;        SV_INIT.svs.clients[i].lastmessage = SV_INIT.svs.realtime; // don't timeout        SV_INIT.svs.clients[i].lastconnect = SV_INIT.svs.realtime;        Com.DPrintf("new client added.\n");    }        /**      * Checks if the rcon password is corect.     */    public static int Rcon_Validate() {        if (0 == SV_MAIN.rcon_password.string.length())            return 0;        if (0 != Lib.strcmp(Cmd.Argv(1), SV_MAIN.rcon_password.string))            return 0;        return 1;    }    /**     * A client issued an rcon command. Shift down the remaining args Redirect     * all printfs fromt hte server to the client.     */    public static void SVC_RemoteCommand() {        int i;        String remaining;        i = Rcon_Validate();        String msg = Lib.CtoJava(Globals.net_message.data, 4, 1024);        if (i == 0)            Com.Printf("Bad rcon from " + NET.AdrToString(Globals.net_from)                    + ":\n" + msg + "\n");        else            Com.Printf("Rcon from " + NET.AdrToString(Globals.net_from) + ":\n"                    + msg + "\n");        Com.BeginRedirect(Defines.RD_PACKET, SV_SEND.sv_outputbuf,                Defines.SV_OUTPUTBUF_LENGTH, new Com.RD_Flusher() {                    public void rd_flush(int target, StringBuffer buffer) {                        SV_SEND.SV_FlushRedirect(target, Lib.stringToBytes(buffer.toString()));                    }                });        if (0 == Rcon_Validate()) {            Com.Printf("Bad rcon_password.\n");        } else {            remaining = "";            for (i = 2; i < Cmd.Argc(); i++) {                remaining += Cmd.Argv(i);                remaining += " ";            }            Cmd.ExecuteString(remaining);        }        Com.EndRedirect();    }    /**     * A connectionless packet has four leading 0xff characters to distinguish     * it from a game channel. Clients that are in the game can still send     * connectionless packets. It is used also by rcon commands.     */    public static void SV_ConnectionlessPacket() {        String s;        String c;        MSG.BeginReading(Globals.net_message);        MSG.ReadLong(Globals.net_message); // skip the -1 marker        s = MSG.ReadStringLine(Globals.net_message);        Cmd.TokenizeString(s.toCharArray(), false);        c = Cmd.Argv(0);                //for debugging purposes         //Com.Printf("Packet " + NET.AdrToString(Netchan.net_from) + " : " + c + "\n");        //Com.Printf(Lib.hexDump(net_message.data, 64, false) + "\n");        if (0 == Lib.strcmp(c, "ping"))            SVC_Ping();        else if (0 == Lib.strcmp(c, "ack"))            SVC_Ack();        else if (0 == Lib.strcmp(c, "status"))            SVC_Status();        else if (0 == Lib.strcmp(c, "info"))            SVC_Info();        else if (0 == Lib.strcmp(c, "getchallenge"))            SVC_GetChallenge();        else if (0 == Lib.strcmp(c, "connect"))            SVC_DirectConnect();        else if (0 == Lib.strcmp(c, "rcon"))            SVC_RemoteCommand();        else {            Com.Printf("bad connectionless packet from "                    + NET.AdrToString(Globals.net_from) + "\n");            Com.Printf("[" + s + "]\n");            Com.Printf("" + Lib.hexDump(Globals.net_message.data, 128, false));        }    }    /**     * Updates the cl.ping variables.     */    public static void SV_CalcPings() {        int i, j;        client_t cl;        int total, count;        for (i = 0; i < SV_MAIN.maxclients.value; i++) {            cl = SV_INIT.svs.clients[i];            if (cl.state != Defines.cs_spawned)                continue;            total = 0;            count = 0;            for (j = 0; j < Defines.LATENCY_COUNTS; j++) {                if (cl.frame_latency[j] > 0) {                    count++;                    total += cl.frame_latency[j];                }            }            if (0 == count)                cl.ping = 0;            else                cl.ping = total / count;            // let the game dll know about the ping            cl.edict.client.ping = cl.ping;        }    }    /**     * Every few frames, gives all clients an allotment of milliseconds for     * their command moves. If they exceed it, assume cheating.     */    public static void SV_GiveMsec() {        int i;        client_t cl;        if ((SV_INIT.sv.framenum & 15) != 0)            return;        for (i = 0; i < SV_MAIN.maxclients.value; i++) {            cl = SV_INIT.svs.clients[i];            if (cl.state == Defines.cs_free)                continue;            cl.commandMsec = 1800; // 1600 + some slop        }    }    /**     * Reads packets from the network or loopback.     */    public static void SV_ReadPackets() {        int i;        client_t cl;        int qport = 0;        while (NET.GetPacket(Defines.NS_SERVER, Globals.net_from,                Globals.net_message)) {            // check for connectionless packet (0xffffffff) first            if ((Globals.net_message.data[0] == -1)                    && (Globals.net_message.data[1] == -1)                    && (Globals.net_message.data[2] == -1)                    && (Globals.net_message.data[3] == -1)) {                SV_ConnectionlessPacket();                continue;            }            // read the qport out of the message so we can fix up            // stupid address translating routers            MSG.BeginReading(Globals.net_message);            MSG.ReadLong(Globals.net_message); // sequence number            MSG.ReadLong(Globals.net_message); // sequence number            qport = MSG.ReadShort(Globals.net_message) & 0xffff;            // check for packets from connected clients            for (i = 0; i < SV_MAIN.maxclients.value; i++) {                cl = SV_INIT.svs.clients[i];                if (cl.state == Defines.cs_free)                    continue;                if (!NET.CompareBaseAdr(Globals.net_from,                        cl.netchan.remote_address))                    continue;                if (cl.netchan.qport != qport)                    continue;                if (cl.netchan.remote_address.port != Globals.net_from.port) {                    Com.Printf("SV_ReadPackets: fixing up a translated port\n");                    cl.netchan.remote_address.port = Globals.net_from.port;                }                if (Netchan.Process(cl.netchan, Globals.net_message)) {                    // this is a valid, sequenced packet, so process it                    if (cl.state != Defines.cs_zombie) {                        cl.lastmessage = SV_INIT.svs.realtime; // don't timeout                        SV_USER.SV_ExecuteClientMessage(cl);                    }                }                break;            }            if (i != SV_MAIN.maxclients.value)                continue;        }    }    /**     * If a packet has not been received from a client for timeout.value     * seconds, drop the conneciton. Server frames are used instead of realtime     * to avoid dropping the local client while debugging.     *      * When a client is normally dropped, the client_t goes into a zombie state     * for a few seconds to make sure any final reliable message gets resent if     * necessary.     */    public static void SV_CheckTimeouts() {        int i;        client_t cl;        int droppoint;        int zombiepoint;        droppoint = (int) (SV_INIT.svs.realtime - 1000 * SV_MAIN.timeout.value);        zombiepoint = (int) (SV_INIT.svs.realtime - 1000 * SV_MAIN.zombietime.value);        for (i = 0; i < SV_MAIN.maxclients.value; i++) {            cl = SV_INIT.svs.clients[i];            // message times may be wrong across a changelevel            if (cl.lastmessage > SV_INIT.svs.realtime)                cl.lastmessage = SV_INIT.svs.realtime;            if (cl.state == Defines.cs_zombie && cl.lastmessage < zombiepoint) {                cl.state = Defines.cs_free; // can now be reused                continue;            }            if ((cl.state == Defines.cs_connected || cl.state == Defines.cs_spawned)                    && cl.lastmessage < droppoint) {                SV_SEND.SV_BroadcastPrintf(Defines.PRINT_HIGH, cl.name                        + " timed out\n");                SV_DropClient(cl);                cl.state = Defines.cs_free; // don't bother with zombie state            }        }    }    /**     * SV_PrepWorldFrame     * 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -