drop position sync code, remove -fsigned-char + fix broken code

master
Daniel Kolesa 2020-04-23 19:03:25 +02:00
parent f835b6e046
commit afba5940ef
9 changed files with 14 additions and 333 deletions

View File

@ -218,91 +218,6 @@ namespace game
const char *chatcolorname(gameent *d) { return colorname(d); }
void toserver(char *text) { conoutf(CON_CHAT, "%s", text); }
static void sendposition(gameent *d, packetbuf &q)
{
putint(q, N_POS);
putuint(q, d->clientnum);
// 3 bits phys state, 1 bit life sequence, 2 bits move, 2 bits strafe
uchar physstate = d->physstate | ((d->lifesequence&1)<<3) | ((d->move&3)<<4) | ((d->strafe&3)<<6);
q.put(physstate);
ivec o = ivec(vec(d->o.x, d->o.y, d->o.z-d->eyeheight).mul(DMF));
uint vel = min(int(d->vel.magnitude()*DVELF), 0xFFFF), fall = min(int(d->falling.magnitude()*DVELF), 0xFFFF);
// 3 bits position, 1 bit velocity, 3 bits falling, 1 bit material, 1 bit crouching
uint flags = 0;
if(o.x < 0 || o.x > 0xFFFF) flags |= 1<<0;
if(o.y < 0 || o.y > 0xFFFF) flags |= 1<<1;
if(o.z < 0 || o.z > 0xFFFF) flags |= 1<<2;
if(vel > 0xFF) flags |= 1<<3;
if(fall > 0)
{
flags |= 1<<4;
if(fall > 0xFF) flags |= 1<<5;
if(d->falling.x || d->falling.y || d->falling.z > 0) flags |= 1<<6;
}
if((lookupmaterial(d->feetpos())&MATF_CLIP) == MAT_GAMECLIP) flags |= 1<<7;
if(d->crouching < 0) flags |= 1<<8;
putuint(q, flags);
loopk(3)
{
q.put(o[k]&0xFF);
q.put((o[k]>>8)&0xFF);
if(o[k] < 0 || o[k] > 0xFFFF) q.put((o[k]>>16)&0xFF);
}
uint dir = (d->yaw < 0 ? 360 + int(d->yaw)%360 : int(d->yaw)%360) + clamp(int(d->pitch+90), 0, 180)*360;
q.put(dir&0xFF);
q.put((dir>>8)&0xFF);
q.put(clamp(int(d->roll+90), 0, 180));
q.put(vel&0xFF);
if(vel > 0xFF) q.put((vel>>8)&0xFF);
float velyaw, velpitch;
vectoyawpitch(d->vel, velyaw, velpitch);
uint veldir = (velyaw < 0 ? 360 + int(velyaw)%360 : int(velyaw)%360) + clamp(int(velpitch+90), 0, 180)*360;
q.put(veldir&0xFF);
q.put((veldir>>8)&0xFF);
if(fall > 0)
{
q.put(fall&0xFF);
if(fall > 0xFF) q.put((fall>>8)&0xFF);
if(d->falling.x || d->falling.y || d->falling.z > 0)
{
float fallyaw, fallpitch;
vectoyawpitch(d->falling, fallyaw, fallpitch);
uint falldir = (fallyaw < 0 ? 360 + int(fallyaw)%360 : int(fallyaw)%360) + clamp(int(fallpitch+90), 0, 180)*360;
q.put(falldir&0xFF);
q.put((falldir>>8)&0xFF);
}
}
}
void sendposition(gameent *d, bool reliable)
{
if(d->state != CS_ALIVE && d->state != CS_EDITING) return;
packetbuf q(100, reliable ? ENET_PACKET_FLAG_RELIABLE : 0);
sendposition(d, q);
sendclientpacket(q.finalize(), 0);
}
void sendpositions()
{
loopv(players)
{
gameent *d = players[i];
if((d == player1) && (d->state == CS_ALIVE || d->state == CS_EDITING))
{
packetbuf q(100);
sendposition(d, q);
for(int j = i+1; j < players.length(); j++)
{
gameent *d = players[j];
if((d == player1) && (d->state == CS_ALIVE || d->state == CS_EDITING))
sendposition(d, q);
}
sendclientpacket(q.finalize(), 0);
break;
}
}
}
void sendmessages()
{
packetbuf p(MAXTRANS);
@ -328,7 +243,6 @@ namespace game
static int lastupdate = -1000;
if(totalmillis - lastupdate < 40 && !force) return; // don't update faster than 30fps
lastupdate = totalmillis;
sendpositions();
sendmessages();
flushclient();
}
@ -341,113 +255,6 @@ namespace game
sendclientpacket(p.finalize(), 1);
}
void updatepos(gameent *d)
{
// update the position of other clients in the game in our world
// don't care if he's in the scenery or other players,
// just don't overlap with our client
const float r = player1->radius+d->radius;
const float dx = player1->o.x-d->o.x;
const float dy = player1->o.y-d->o.y;
const float dz = player1->o.z-d->o.z;
const float rz = player1->aboveeye+d->eyeheight;
const float fx = (float)fabs(dx), fy = (float)fabs(dy), fz = (float)fabs(dz);
if(fx<r && fy<r && fz<rz && player1->state!=CS_SPECTATOR && d->state!=CS_DEAD)
{
if(fx<fy) d->o.y += dy<0 ? r-fy : -(r-fy); // push aside
else d->o.x += dx<0 ? r-fx : -(r-fx);
}
int lagtime = totalmillis-d->lastupdate;
if(lagtime)
{
if(d->state!=CS_SPAWNING && d->lastupdate) d->plag = (d->plag*5+lagtime)/6;
d->lastupdate = totalmillis;
}
}
void parsepositions(ucharbuf &p)
{
int type;
while(p.remaining()) switch(type = getint(p))
{
case N_POS: // position of another client
{
int cn = getuint(p), physstate = p.get(), flags = getuint(p);
vec o, vel, falling;
float yaw, pitch, roll;
loopk(3)
{
int n = p.get(); n |= p.get()<<8; if(flags&(1<<k)) { n |= p.get()<<16; if(n&0x800000) n |= ~0U<<24; }
o[k] = n/DMF;
}
int dir = p.get(); dir |= p.get()<<8;
yaw = dir%360;
pitch = clamp(dir/360, 0, 180)-90;
roll = clamp(int(p.get()), 0, 180)-90;
int mag = p.get(); if(flags&(1<<3)) mag |= p.get()<<8;
dir = p.get(); dir |= p.get()<<8;
vecfromyawpitch(dir%360, clamp(dir/360, 0, 180)-90, 1, 0, vel);
vel.mul(mag/DVELF);
if(flags&(1<<4))
{
mag = p.get(); if(flags&(1<<5)) mag |= p.get()<<8;
if(flags&(1<<6))
{
dir = p.get(); dir |= p.get()<<8;
vecfromyawpitch(dir%360, clamp(dir/360, 0, 180)-90, 1, 0, falling);
}
else falling = vec(0, 0, -1);
falling.mul(mag/DVELF);
}
else falling = vec(0, 0, 0);
int seqcolor = (physstate>>3)&1;
gameent *d = getclient(cn);
if(!d || d->lifesequence < 0 || seqcolor!=(d->lifesequence&1) || d->state==CS_DEAD) continue;
float oldyaw = d->yaw, oldpitch = d->pitch, oldroll = d->roll;
d->yaw = yaw;
d->pitch = pitch;
d->roll = roll;
d->move = (physstate>>4)&2 ? -1 : (physstate>>4)&1;
d->strafe = (physstate>>6)&2 ? -1 : (physstate>>6)&1;
d->crouching = (flags&(1<<8))!=0 ? -1 : abs(d->crouching);
vec oldpos(d->o);
d->o = o;
d->o.z += d->eyeheight;
d->vel = vel;
d->falling = falling;
d->physstate = physstate&7;
updatephysstate(d);
updatepos(d);
if(smoothmove && d->smoothmillis>=0 && oldpos.dist(d->o) < smoothdist)
{
d->newpos = d->o;
d->newyaw = d->yaw;
d->newpitch = d->pitch;
d->newroll = d->roll;
d->o = oldpos;
d->yaw = oldyaw;
d->pitch = oldpitch;
d->roll = oldroll;
(d->deltapos = oldpos).sub(d->newpos);
d->deltayaw = oldyaw - d->newyaw;
if(d->deltayaw > 180) d->deltayaw -= 360;
else if(d->deltayaw < -180) d->deltayaw += 360;
d->deltapitch = oldpitch - d->newpitch;
d->deltaroll = oldroll - d->newroll;
d->smoothmillis = lastmillis;
}
else d->smoothmillis = 0;
if(d->state==CS_LAGGED || d->state==CS_SPAWNING) d->state = CS_ALIVE;
break;
}
default:
neterr("type");
return;
}
}
void parsestate(gameent *d, ucharbuf &p, bool resume = false)
{
if(!d) { static gameent dummy; d = &dummy; }
@ -464,7 +271,7 @@ namespace game
static char text[MAXTRANS];
int type;
while(p.remaining()) switch(type = getint(p))
while(p.remaining()) switch((type = getint(p)))
{
case N_SERVINFO: // welcome messsage from the server
{
@ -614,10 +421,6 @@ namespace game
if(p.packet->flags&ENET_PACKET_FLAG_UNSEQUENCED) return;
switch(chan)
{
case 0:
parsepositions(p);
break;
case 1:
parsemessages(-1, NULL, p);
break;

View File

@ -107,9 +107,6 @@ namespace entities
void editent(int i, bool local)
{
extentity &e = *ents[i];
//e.flags = 0;
if(local) addmsg(N_EDITENT, "rii3ii5", i, (int)(e.o.x*DMF), (int)(e.o.y*DMF), (int)(e.o.z*DMF), e.type, e.attr1, e.attr2, e.attr3, e.attr4, e.attr5);
}
float dropheight(entity &e)

View File

@ -404,15 +404,7 @@ namespace game
void msgsound(int n, physent *d)
{
if(!d || d==player1)
{
addmsg(N_SOUND, "ci", d, n);
playsound(n);
}
else
{
playsound(n, &d->o);
}
playsound(n);
}
int numdynents() { return players.length(); }

View File

@ -99,37 +99,25 @@ enum
enum
{
N_CONNECT = 0, N_SERVINFO, N_WELCOME, N_INITCLIENT, N_POS, N_TEXT, N_SOUND, N_CDIS,
N_DIED, N_DAMAGE, N_HITPUSH, N_SHOTFX, N_EXPLODEFX,
N_TRYSPAWN, N_SPAWNSTATE, N_SPAWN, N_FORCEDEATH,
N_CONNECT = 0, N_SERVINFO, N_WELCOME, N_INITCLIENT, N_CDIS,
N_TRYSPAWN, N_SPAWNSTATE, N_SPAWN,
N_MAPCHANGE,
N_PING, N_PONG, N_CLIENTPING,
N_SERVMSG, N_ITEMLIST, N_RESUME,
N_EDITMODE, N_EDITENT, N_EDITF, N_EDITT, N_EDITM, N_FLIP, N_COPY, N_PASTE, N_ROTATE, N_REPLACE, N_DELCUBE, N_CALCLIGHT, N_REMIP, N_EDITVSLOT, N_UNDO, N_REDO, N_NEWMAP, N_GETMAP, N_SENDMAP, N_CLIPBOARD, N_EDITVAR,
N_SPECTATOR, N_SETTEAM,
N_NEWMAP,
N_RESUME,
N_CLIENT,
N_PAUSEGAME, N_GAMESPEED,
N_MAPCRC, N_CHECKMAPS,
N_SWITCHNAME, N_SWITCHMODEL, N_SWITCHCOLOR, N_SWITCHTEAM,
N_SERVCMD,
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_INITCLIENT, 0, N_POS, 0, N_TEXT, 0, N_SOUND, 2, N_CDIS, 2,
N_DIED, 5, N_DAMAGE, 5, N_HITPUSH, 7, N_SHOTFX, 10, N_EXPLODEFX, 4,
N_TRYSPAWN, 1, N_SPAWNSTATE, 8, N_SPAWN, 3, N_FORCEDEATH, 2,
N_CONNECT, 0, N_SERVINFO, 0, N_WELCOME, 1, N_INITCLIENT, 0, N_CDIS, 2,
N_TRYSPAWN, 1, N_SPAWNSTATE, 8, N_SPAWN, 2,
N_MAPCHANGE, 0,
N_PING, 2, N_PONG, 2, N_CLIENTPING, 2,
N_SERVMSG, 0, N_ITEMLIST, 0, N_RESUME, 0,
N_EDITMODE, 2, N_EDITENT, 11, N_EDITF, 16, N_EDITT, 16, N_EDITM, 16, N_FLIP, 14, N_COPY, 14, N_PASTE, 14, N_ROTATE, 15, N_REPLACE, 17, N_DELCUBE, 14, N_CALCLIGHT, 1, N_REMIP, 1, N_EDITVSLOT, 16, N_UNDO, 0, N_REDO, 0, N_NEWMAP, 2, N_GETMAP, 1, N_SENDMAP, 0, N_EDITVAR, 0,
N_SPECTATOR, 3, N_SETTEAM, 0,
N_NEWMAP, 2,
N_RESUME, 0,
N_CLIENT, 0,
N_PAUSEGAME, 0, N_GAMESPEED, 0,
N_MAPCRC, 0, N_CHECKMAPS, 1,
N_SWITCHNAME, 0, N_SWITCHMODEL, 2, N_SWITCHCOLOR, 2, N_SWITCHTEAM, 2,
N_SERVCMD, 0,
-1
};

View File

@ -60,7 +60,7 @@ namespace server
string name;
bool connected, local, timesync;
servstate state;
vector<uchar> position, messages;
vector<uchar> messages;
uchar *wsdata;
int wslen;
int ping;
@ -88,7 +88,6 @@ namespace server
{
name[0] = 0;
connected = local = false;
position.setsize(0);
messages.setsize(0);
ping = 0;
mapchange();
@ -215,47 +214,6 @@ namespace server
}
}
void flushclientposition(clientinfo &ci)
{
if(ci.position.empty() || !hasnonlocalclients()) return;
packetbuf p(ci.position.length(), 0);
p.put(ci.position.getbuf(), ci.position.length());
ci.position.setsize(0);
sendpacket(-1, 0, p.finalize(), ci.ownernum);
}
static void sendpositions(worldstate &ws, ucharbuf &wsbuf)
{
if(wsbuf.empty()) return;
int wslen = wsbuf.length();
wsbuf.put(wsbuf.buf, wslen);
loopv(clients)
{
clientinfo &ci = *clients[i];
uchar *data = wsbuf.buf;
int size = wslen;
if(ci.wsdata >= wsbuf.buf) { data = ci.wsdata + ci.wslen; size -= ci.wslen; }
if(size <= 0) continue;
ENetPacket *packet = enet_packet_create(data, size, ENET_PACKET_FLAG_NO_ALLOCATE);
sendpacket(ci.clientnum, 0, packet);
if(packet->referenceCount) { ws.uses++; packet->freeCallback = cleanworldstate; }
else enet_packet_destroy(packet);
}
wsbuf.offset(wsbuf.length());
}
static inline void addposition(worldstate &ws, ucharbuf &wsbuf, int mtu, clientinfo &bi, clientinfo &ci)
{
if(bi.position.empty()) return;
if(wsbuf.length() + bi.position.length() > mtu) sendpositions(ws, wsbuf);
int offset = wsbuf.length();
wsbuf.put(bi.position.getbuf(), bi.position.length());
bi.position.setsize(0);
int len = wsbuf.length() - offset;
if(ci.wsdata < wsbuf.buf) { ci.wsdata = &wsbuf.buf[offset]; ci.wslen = len; }
else ci.wslen += len;
}
static void sendmessages(worldstate &ws, ucharbuf &wsbuf)
{
if(wsbuf.empty()) return;
@ -299,7 +257,6 @@ namespace server
clientinfo &ci = *clients[i];
ci.overflow = 0;
ci.wsdata = NULL;
wsmax += ci.position.length();
if(ci.messages.length()) wsmax += 10 + ci.messages.length();
}
if(wsmax <= 0)
@ -313,12 +270,6 @@ namespace server
if(mtu <= 0) mtu = ws.len;
ucharbuf wsbuf(ws.data, ws.len);
loopv(clients)
{
clientinfo &ci = *clients[i];
addposition(ws, wsbuf, mtu, ci, ci);
}
sendpositions(ws, wsbuf);
loopv(clients)
{
clientinfo &ci = *clients[i];
addmessages(ws, wsbuf, mtu, ci, ci);
@ -415,14 +366,6 @@ namespace server
return 1;
}
void sendresume(clientinfo *ci)
{
servstate &gs = ci->state;
sendf(-1, 1, "ri3ii", N_RESUME, ci->clientnum, gs.state,
gs.lifesequence,
-1);
}
void sendinitclient(clientinfo *ci)
{
packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
@ -476,11 +419,6 @@ namespace server
void unspectate(clientinfo *ci)
{
if(shouldspectate(ci)) return;
ci->state.state = CS_DEAD;
ci->state.respawn();
ci->state.lasttimeplayed = lastmillis;
sendf(-1, 1, "ri3", N_SPECTATOR, ci->clientnum, 0);
}
void sendservinfo(clientinfo *ci)
@ -613,39 +551,6 @@ namespace server
int curmsg;
while((curmsg = p.length()) < p.maxlen) switch(type = checktype(getint(p), ci))
{
case N_POS:
{
int pcn = getuint(p);
p.get();
uint flags = getuint(p);
clientinfo *cp = getinfo(pcn);
if(cp && pcn != sender && cp->ownernum != sender) cp = NULL;
vec pos;
loopk(3)
{
int n = p.get(); n |= p.get()<<8; if(flags&(1<<k)) { n |= p.get()<<16; if(n&0x800000) n |= ~0U<<24; }
pos[k] = n/DMF;
}
loopk(3) p.get();
int mag = p.get(); if(flags&(1<<3)) mag |= p.get()<<8;
int dir = p.get(); dir |= p.get()<<8;
if(flags&(1<<4))
{
p.get(); if(flags&(1<<5)) p.get();
if(flags&(1<<6)) loopk(2) p.get();
}
if(cp)
{
if((!ci->local || hasnonlocalclients()) && (cp->state.state==CS_ALIVE || cp->state.state==CS_EDITING))
{
cp->position.setsize(0);
while(curmsg<p.length()) cp->position.add(p.buf[curmsg++]);
}
cp->state.o = pos;
}
break;
}
case N_TRYSPAWN:
if(!ci || !cq || cq->state.state!=CS_DEAD || cq->state.lastspawn>=0) break;
sendspawn(cq);

View File

@ -2,8 +2,5 @@ octacore_includes = [
include_directories('.', 'shared', 'engine', 'game', 'enet/include')
]
# FIXME: remove, for now without this the engine behaves wonky
add_global_arguments('-fsigned-char', language: 'cpp')
subdir('enet')
subdir('client')

View File

@ -73,7 +73,7 @@ struct physent // base entity type, can be affe
int inwater;
bool jumping;
char move, strafe, crouching;
signed char move, strafe, crouching;
uchar physstate; // one of PHYS_* above
uchar state, editstate; // one of CS_* above

View File

@ -106,8 +106,8 @@ void putint(vector<uchar> &p, int n) { putint_(p, n); }
int getint(ucharbuf &p)
{
int c = (char)p.get();
if(c==-128) { int n = p.get(); n |= char(p.get())<<8; return n; }
int c = (signed char)p.get();
if(c==-128) { int n = p.get(); n |= ((signed char)p.get())<<8; return n; }
else if(c==-127) { int n = p.get(); n |= p.get()<<8; n |= p.get()<<16; return n|(p.get()<<24); }
else return c;
}

View File

@ -370,7 +370,6 @@ struct databuf
}
};
typedef databuf<char> charbuf;
typedef databuf<uchar> ucharbuf;
struct packetbuf : ucharbuf