diff --git a/src/engine/client.cc b/src/engine/client.cc index 80fa08a..43d0091 100644 --- a/src/engine/client.cc +++ b/src/engine/client.cc @@ -22,17 +22,6 @@ ICOMMAND(disconnect, "", (), trydisconnect()); ICOMMAND(localconnect, "", (), { if(!isconnected()) localconnect(); }); ICOMMAND(localdisconnect, "", (), { if(haslocalclients()) localdisconnect(); }); -void localservertoclient(int chan, ENetPacket *packet) // processes any updates from the server -{ - packetbuf p(packet); - game::parsepacketclient(chan, p); -} - -void sendclientpacket(ENetPacket *packet, int chan) -{ - localclienttoserver(chan, packet); -} - void clientkeepalive() {} void gets2c() {} diff --git a/src/engine/main.cc b/src/engine/main.cc index 7cf7c0b..e5158d1 100644 --- a/src/engine/main.cc +++ b/src/engine/main.cc @@ -1183,7 +1183,6 @@ int main(int argc, char **argv) checksleep(lastmillis); server::serverupdate(); - server::sendpackets(); if(frames) updatefpshistory(elapsedtime); frames++; diff --git a/src/engine/server.cc b/src/engine/server.cc index 424e00a..c9a8404 100644 --- a/src/engine/server.cc +++ b/src/engine/server.cc @@ -100,7 +100,6 @@ client &addclient(int type) c->num = clients.length(); clients.add(c); } - c->info = server::newclientinfo(); c->type = type; switch(type) { @@ -118,84 +117,12 @@ void delclient(client *c) case ST_EMPTY: return; } c->type = ST_EMPTY; - if(c->info) - { - server::deleteclientinfo(c->info); - c->info = NULL; - } } void cleanupserver() { } -void process(ENetPacket *packet, int sender, int chan); - -void *getclientinfo(int i) { return !clients.inrange(i) || clients[i]->type==ST_EMPTY ? NULL : clients[i]->info; } - -void sendpacket(int n, int chan, ENetPacket *packet, int exclude) -{ - if(n<0) - { - loopv(clients) if(i!=exclude && server::allowbroadcast(i)) sendpacket(i, chan, packet); - return; - } - switch(clients[n]->type) - { - case ST_LOCAL: - localservertoclient(chan, packet); - break; - } -} - -ENetPacket *sendf(int cn, int chan, const char *format, ...) -{ - int exclude = -1; - bool reliable = false; - if(*format=='r') { reliable = true; ++format; } - packetbuf p(MAXTRANS, reliable ? ENET_PACKET_FLAG_RELIABLE : 0); - va_list args; - va_start(args, format); - while(*format) switch(*format++) - { - case 'x': - exclude = va_arg(args, int); - break; - - case 'v': - { - int n = va_arg(args, int); - int *v = va_arg(args, int *); - loopi(n) putint(p, v[i]); - break; - } - - case 'i': - { - int n = isdigit(*format) ? *format++-'0' : 1; - loopi(n) putint(p, va_arg(args, int)); - break; - } - case 'f': - { - int n = isdigit(*format) ? *format++-'0' : 1; - loopi(n) putfloat(p, (float)va_arg(args, double)); - break; - } - case 's': sendstring(va_arg(args, const char *), p); break; - case 'm': - { - int n = va_arg(args, int); - p.put(va_arg(args, uchar *), n); - break; - } - } - va_end(args); - ENetPacket *packet = p.finalize(); - sendpacket(cn, chan, packet, exclude); - return packet->referenceCount > 0 ? packet : NULL; -} - const char *disconnectreason(int reason) { switch(reason) @@ -222,20 +149,6 @@ void kicknonlocalclients(int reason) { } -void process(ENetPacket *packet, int sender, int chan) // sender may be -1 -{ - packetbuf p(packet); - server::parsepacket(sender, chan, p); - if(p.overread()) { disconnect_client(sender, DISC_EOP); return; } -} - -void localclienttoserver(int chan, ENetPacket *packet) -{ - client *c = NULL; - loopv(clients) if(clients[i]->type==ST_LOCAL) { c = clients[i]; break; } - if(c) process(packet, c->num, chan); -} - void updatetime() { } @@ -260,7 +173,6 @@ void localconnect() client &c = addclient(ST_LOCAL); copystring(c.hostname, "local"); game::gameconnect(false); - server::localconnect(c.num); } void logoutfv(const char *fmt, va_list args) diff --git a/src/game/client.cc b/src/game/client.cc index 0167dea..f369946 100644 --- a/src/game/client.cc +++ b/src/game/client.cc @@ -1,5 +1,7 @@ #include "game.hh" +extern void clearmainmenu(); + namespace game { VARP(minradarscale, 0, 384, 10000); @@ -75,8 +77,10 @@ namespace game void changemap(const char *name, int mode) // request map change, server may ignore { - server::forcemap(name, mode); - if(!isconnected()) localconnect(); + changemapserv(name, 0); + localconnect(); + clearmainmenu(); /* XXX hack */ + connected = true; } void changemap(const char *name) { @@ -91,7 +95,10 @@ namespace game void newmap(int size) { - addmsg(N_NEWMAP, "ri", size); + if(size>=0) emptymap(size, true, NULL); + else enlargemap(true); + localconnect(); + connected = true; } void edittrigger(const selinfo &sel, int op, int arg1, int arg2, int arg3, const VSlot *vs) @@ -107,63 +114,6 @@ namespace game int scaletime(int t) { return t*100; } - // collect c2s messages conveniently - vector messages; - int messagecn = -1, messagereliable = false; - - bool addmsg(int type, const char *fmt, ...) - { - if(!connected) return false; - static uchar buf[MAXTRANS]; - ucharbuf p(buf, sizeof(buf)); - putint(p, type); - int numi = 1, numf = 0, nums = 0; - bool reliable = false; - if(fmt) - { - va_list args; - va_start(args, fmt); - while(*fmt) switch(*fmt++) - { - case 'r': reliable = true; break; - case 'c': - { - break; - } - case 'v': - { - int n = va_arg(args, int); - int *v = va_arg(args, int *); - loopi(n) putint(p, v[i]); - numi += n; - break; - } - - case 'i': - { - int n = isdigit(*fmt) ? *fmt++-'0' : 1; - loopi(n) putint(p, va_arg(args, int)); - numi += n; - break; - } - case 'f': - { - int n = isdigit(*fmt) ? *fmt++-'0' : 1; - loopi(n) putfloat(p, (float)va_arg(args, double)); - numf += n; - break; - } - case 's': sendstring(va_arg(args, const char *), p); nums++; break; - } - va_end(args); - } - int num = nums || numf ? 0 : numi, msgsize = server::msgsizelookup(type); - if(msgsize && num!=msgsize) { fatal("inconsistent msg size for %d (%d != %d)", type, num, msgsize); } - if(reliable) messagereliable = true; - messages.put(buf, p.length()); - return true; - } - void connectfail() { } @@ -179,11 +129,7 @@ namespace game player1->clientnum = -1; if(editmode) toggleedit(); sessionid = 0; - messages.setsize(0); - messagereliable = false; - messagecn = -1; player1->respawn(); - player1->lifesequence = 0; player1->state = CS_ALIVE; if(cleanup) { @@ -192,112 +138,5 @@ namespace game } void toserver(char *text) { conoutf(CON_CHAT, "%s", text); } - - void sendmessages() - { - packetbuf p(MAXTRANS); - if(messages.length()) - { - p.put(messages.getbuf(), messages.length()); - messages.setsize(0); - if(messagereliable) p.reliable(); - messagereliable = false; - messagecn = -1; - } - sendclientpacket(p.finalize(), 1); - } - - void c2sinfo(bool force) // send update to the server - { - static int lastupdate = -1000; - if(totalmillis - lastupdate < 40 && !force) return; // don't update faster than 30fps - lastupdate = totalmillis; - sendmessages(); - } - - void sendintro() - { - packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE); - putint(p, N_CONNECT); - sendstring(player1->name, p); - sendclientpacket(p.finalize(), 1); - } - - void parsestate(gameent *d, ucharbuf &p, bool resume = false) - { - if(!d) { static gameent dummy; d = &dummy; } - if(resume) - { - if(d==player1) getint(p); - else d->state = getint(p); - } - d->lifesequence = getint(p); - } - - void parsemessages(int cn, gameent *d, ucharbuf &p) - { - static char text[MAXTRANS]; - int type; - - while(p.remaining()) switch((type = getint(p))) - { - case N_SERVINFO: // welcome messsage from the server - { - int mycn = getint(p); - sessionid = getint(p); - player1->clientnum = mycn; // we are now connected - sendintro(); - break; - } - - case N_WELCOME: - { - connected = true; - notifywelcome(); - break; - } - - case N_MAPCHANGE: - getstring(text, p); - changemapserv(text, 0); - break; - - case N_SPAWN: - { - printf("spawn\n"); - if(d) - { - d->respawn(); - } - parsestate(d, p); - if(!d) break; - d->state = CS_SPAWNING; - break; - } - - case N_NEWMAP: - { - int size = getint(p); - if(size>=0) emptymap(size, true, NULL); - else enlargemap(true); - break; - } - - default: - neterr("type", cn < 0); - return; - } - } - - void parsepacketclient(int chan, packetbuf &p) // processes any updates from the server - { - if(p.packet->flags&ENET_PACKET_FLAG_UNSEQUENCED) return; - switch(chan) - { - case 1: - parsemessages(-1, NULL, p); - break; - } - } } diff --git a/src/game/game.cc b/src/game/game.cc index 7bf1aef..7776e60 100644 --- a/src/game/game.cc +++ b/src/game/game.cc @@ -57,18 +57,16 @@ namespace game void updateworld() // main game update loop { if(!maptime) { maptime = lastmillis; maprealtime = totalmillis; return; } - if(!curtime) { gets2c(); if(player1->clientnum>=0) c2sinfo(); return; } + if(!curtime) { return; } physicsframe(); moveragdolls(); - gets2c(); if(connected) { crouchplayer(player1, 10, true); moveplayer(player1, 10, true); entities::checkitems(player1); } - if(player1->clientnum>=0) c2sinfo(); // do this last, to reduce the effective frame lag } void spawnplayer(gameent *d) // place at random spawn diff --git a/src/game/game.hh b/src/game/game.hh index d0d3387..97c2f6e 100644 --- a/src/game/game.hh +++ b/src/game/game.hh @@ -77,31 +77,6 @@ struct gameentity : extentity { }; -enum -{ - M_EDIT = 1<<0 -}; - -// network messages codes, c2s, c2c, s2c - -enum -{ - N_CONNECT = 0, N_SERVINFO, N_WELCOME, - N_SPAWN, - N_MAPCHANGE, - N_NEWMAP, - NUMMSG -}; - -static const int msgsizes[] = // size inclusive message token, 0 for variable or not-checked sizes -{ - N_CONNECT, 0, N_SERVINFO, 0, N_WELCOME, 1, - N_SPAWN, 2, - N_MAPCHANGE, 0, - N_NEWMAP, 2, - -1 -}; - #define TESSERACT_SERVER_PORT 42000 #define TESSERACT_LANINFO_PORT 41998 @@ -136,7 +111,6 @@ struct gameent : dynent, gamestate { int weight; // affects the effectiveness of hitpush int clientnum, lastupdate, plag, ping; - int lifesequence; // sequence id for each respawn, used in damage test int respawned; int lastaction; editinfo *edit; @@ -149,7 +123,7 @@ struct gameent : dynent, gamestate vec muzzle; - gameent() : weight(100), clientnum(-1), lastupdate(0), plag(0), ping(0), lifesequence(0), respawned(-1), edit(NULL), smoothmillis(-1), team(0), playermodel(-1), playercolor(0), ownernum(-1), muzzle(-1, -1, -1) + gameent() : weight(100), clientnum(-1), lastupdate(0), plag(0), ping(0), respawned(-1), edit(NULL), smoothmillis(-1), team(0), playermodel(-1), playercolor(0), ownernum(-1), muzzle(-1, -1, -1) { name[0] = info[0] = 0; respawn(); @@ -175,7 +149,6 @@ struct gameent : dynent, gamestate void startgame() { - lifesequence = -1; respawned = -2; } }; @@ -224,14 +197,10 @@ namespace game // client extern bool connected, remote, demoplayback; extern string servdesc; - extern vector messages; extern int parseplayer(const char *arg); - extern bool addmsg(int type, const char *fmt = NULL, ...); extern void sendmapinfo(); extern void changemap(const char *name, int mode); - extern void c2sinfo(bool force = false); - extern void sendposition(gameent *d, bool reliable = false); // render diff --git a/src/game/server.cc b/src/game/server.cc index 85028e6..23e448a 100644 --- a/src/game/server.cc +++ b/src/game/server.cc @@ -7,104 +7,9 @@ namespace game namespace server { - struct clientinfo; - - struct servstate : gamestate - { - vec o; - int state, editstate; - int lastspawn, lifesequence; - - servstate() : state(CS_DEAD), editstate(CS_DEAD), lifesequence(0) {} - - void reset() - { - state = editstate = CS_DEAD; - - respawn(); - } - - void respawn() - { - gamestate::respawn(); - o = vec(-1e10f, -1e10f, -1e10f); - lastspawn = -1; - } - - void reassign() - { - respawn(); - } - }; - - extern int gamemillis; - - struct clientinfo - { - int clientnum, ownernum, connectmillis, sessionid, overflow; - string name; - bool connected, local, timesync; - servstate state; - vector messages; - uchar *wsdata; - int wslen; - string clientmap; - bool warned; - - clientinfo() { reset(); } - - void mapchange() - { - state.reset(); - overflow = 0; - timesync = false; - clientmap[0] = '\0'; - warned = false; - } - - void reassign() - { - state.reassign(); - timesync = false; - } - - void reset() - { - name[0] = 0; - connected = local = false; - messages.setsize(0); - mapchange(); - } - }; - - int gamemillis = 0; - bool shouldstep = true; - + string smapname = ""; - vector connects, clients; - - void *newclientinfo() { return new clientinfo; } - void deleteclientinfo(void *ci) { delete (clientinfo *)ci; } - - clientinfo *getinfo(int n) - { - return (clientinfo *)getclientinfo(n); - } - - int msgsizelookup(int msg) - { - static int sizetable[NUMMSG] = { -1 }; - if(sizetable[0] < 0) - { - memset(sizetable, -1, sizeof(sizetable)); - for(const int *p = msgsizes; *p >= 0; p += 2) sizetable[p[0]] = p[1]; - } - return msg >= 0 && msg < NUMMSG ? sizetable[msg] : -1; - } - - void sendservmsg(const char *) {} - void serverinit() { smapname[0] = '\0'; @@ -112,290 +17,53 @@ namespace server int numclients(int exclude = -1, bool nospec = true, bool noai = true, bool priv = false) { - int n = 0; - loopv(clients) - { - clientinfo *ci = clients[i]; - if(ci->clientnum!=exclude && (!nospec || ci->state.state!=CS_SPECTATOR || (priv && ci->local))) n++; - } - return n; - } - - bool duplicatename(clientinfo *ci, const char *name) - { - if(!name) name = ci->name; - loopv(clients) if(clients[i]!=ci && !strcmp(name, clients[i]->name)) return true; - return false; + return 0; } int spawntime(int type) { - int np = numclients(-1, true, false); - np = np<3 ? 4 : (np>4 ? 2 : 3); // spawn times are dependent on number of players - int sec = 0; - switch(type) - { - } - return sec*1000; + return 0; } bool delayspawn(int type) { - switch(type) - { - default: - return false; - } + return false; } - int welcomepacket(packetbuf &p, clientinfo *ci); - void sendwelcome(clientinfo *ci); - bool ispaused() { return false; } int scaletime(int t) { return t*100; } - int checktype(int type, clientinfo *ci) - { - return type; - } - - bool sendpackets(bool force) - { - return false; - } - - template - void sendstate(servstate &gs, T &p) - { - putint(p, gs.lifesequence); - } - - void sendwelcome(clientinfo *ci) - { - packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE); - int chan = welcomepacket(p, ci); - sendpacket(ci->clientnum, chan, p.finalize()); - } - - bool hasmap(clientinfo *ci) - { - return true; - } - - int welcomepacket(packetbuf &p, clientinfo *ci) - { - putint(p, N_WELCOME); - putint(p, N_MAPCHANGE); - sendstring(smapname, p); - return 1; - } - - void changemap(const char *s, int mode) - { - gamemillis = 0; - copystring(smapname, s); - - kicknonlocalclients(DISC_LOCAL); - - sendf(-1, 1, "ris", N_MAPCHANGE, smapname); - - loopv(clients) - { - clientinfo *ci = clients[i]; - ci->mapchange(); - } - } - - void forcemap(const char *map, int mode) - { - changemap(map, mode); - } - void serverupdate() { - if(shouldstep) - { - gamemillis += curtime; - } - - loopv(connects) if(totalmillis-connects[i]->connectmillis>15000) disconnect_client(connects[i]->clientnum, DISC_TIMEOUT); - - shouldstep = clients.length() > 0; } - bool shouldspectate(clientinfo *ci) - { - return false; - } - - void unspectate(clientinfo *ci) - { - } - - void sendservinfo(clientinfo *ci) - { - sendf(ci->clientnum, 1, "ri3", N_SERVINFO, ci->clientnum, ci->sessionid); - } - void noclients() { } void localconnect(int n) { - clientinfo *ci = getinfo(n); - ci->clientnum = ci->ownernum = n; - ci->connectmillis = totalmillis; - ci->sessionid = (rnd(0x1000000)*((totalmillis%10000)+1))&0xFFFFFF; - ci->local = true; - - connects.add(ci); - sendservinfo(ci); } void localdisconnect(int n) { - clientdisconnect(n); } int clientconnect(int n, uint ip) { - clientinfo *ci = getinfo(n); - ci->clientnum = ci->ownernum = n; - ci->connectmillis = totalmillis; - ci->sessionid = (rnd(0x1000000)*((totalmillis%10000)+1))&0xFFFFFF; - - connects.add(ci); return DISC_LOCAL; } void clientdisconnect(int n) { - clientinfo *ci = getinfo(n); - if(ci->connected) - { - clients.removeobj(ci); - if(!numclients(-1, false, true)) noclients(); // bans clear when server empties - } - else connects.removeobj(ci); } int reserveclients() { return 3; } bool allowbroadcast(int n) { - clientinfo *ci = getinfo(n); - return ci && ci->connected; - } - - void receivefile(int sender, uchar *data, int len) - { - } - - void connected(clientinfo *ci) - { - shouldstep = true; - - connects.removeobj(ci); - clients.add(ci); - - ci->connected = true; - - sendwelcome(ci); - } - - void parsepacket(int sender, int chan, packetbuf &p) // has to parse exactly each byte of the packet - { - if(sender<0 || p.packet->flags&ENET_PACKET_FLAG_UNSEQUENCED || chan > 2) return; - char text[MAXTRANS]; - int type; - clientinfo *ci = sender>=0 ? getinfo(sender) : NULL, *cq = ci, *cm = ci; - if(ci && !ci->connected) - { - if(chan==0) return; - else if(chan!=1) { disconnect_client(sender, DISC_MSGERR); return; } - else while(p.length() < p.maxlen) switch(checktype(getint(p), ci)) - { - case N_CONNECT: - { - getstring(text, p); - filtertext(text, text, false, false, MAXNAMELEN); - if(!text[0]) copystring(text, "unnamed"); - copystring(ci->name, text, MAXNAMELEN+1); - connected(ci); - break; - } - - default: - disconnect_client(sender, DISC_MSGERR); - return; - } - return; - } - else if(chan==2) - { - receivefile(sender, p.buf, p.maxlen); - return; - } - - #define QUEUE_AI clientinfo *cm = cq; - #define QUEUE_MSG { if(cm && (!cm->local || hasnonlocalclients())) while(curmsgmessages.add(p.buf[curmsg++]); } - #define QUEUE_BUF(body) { \ - if(cm && (!cm->local || hasnonlocalclients())) \ - { \ - curmsg = p.length(); \ - { body; } \ - } \ - } - #define QUEUE_INT(n) QUEUE_BUF(putint(cm->messages, n)) - #define QUEUE_UINT(n) QUEUE_BUF(putuint(cm->messages, n)) - #define QUEUE_STR(text) QUEUE_BUF(sendstring(text, cm->messages)) - int curmsg; - while((curmsg = p.length()) < p.maxlen) switch(type = checktype(getint(p), ci)) - { - case N_SPAWN: - { - int ls = getint(p); - if(!cq || (cq->state.state!=CS_ALIVE && cq->state.state!=CS_DEAD && cq->state.state!=CS_EDITING) || ls!=cq->state.lifesequence || cq->state.lastspawn<0) break; - cq->state.lastspawn = -1; - cq->state.state = CS_ALIVE; - QUEUE_AI; - QUEUE_BUF({ - putint(cm->messages, N_SPAWN); - sendstate(cq->state, cm->messages); - }); - break; - } - - case N_NEWMAP: - { - int size = getint(p); - if(!ci->local && ci->state.state==CS_SPECTATOR) break; - if(size>=0) - { - smapname[0] = '\0'; - } - QUEUE_MSG; - break; - } - - case -1: - disconnect_client(sender, DISC_MSGERR); - return; - - case -2: - disconnect_client(sender, DISC_OVERFLOW); - return; - - default: - { - int size = server::msgsizelookup(type); - if(size<=0) { disconnect_client(sender, DISC_MSGERR); return; } - loopi(size-1) getint(p); - if(cq && (ci != cq || ci->state.state!=CS_SPECTATOR)) { QUEUE_AI; QUEUE_MSG; } - } - } + return true; } int laninfoport() { return TESSERACT_LANINFO_PORT; }