
Posted by Maj.Bitch on January 20, 1999 at
19:32:46:
Title: Server-Client
Protocols (Part IV)
Difficulty: Difficult
By: Philip (aka Maj.Bitch)
Email: peblair@gv.net
Date: 1-20-99
Note: Please give credit where credit is due.
======================================================
//==============================================
void set_map_name(protocol *state,char *mapname){
state->shared->smn(state->shared->smn_arg,mapname);
}
//==============================================
void init_edicts(protocol *state){
unsigned c;
if (state->delta_frame
== 0xffffffff){
memcpy(state->shared->edicts,state->baseline, sizeof(edict)*MAX_EDICTS);
return;}
for (c=0;c<16;c++){
if (state->oldframe_nums[c] != state->delta_frame) continue;
memcpy(state->shared->edicts,state->oldframes[c],
sizeof(edict)*MAX_EDICTS);
return;}
printf(stderr,"Server
requested delta frame we do not have\n");
exit(7);
}
//==============================================
void save_frame(protocol *state){
unsigned c;
for (c=0;c<15;c++){
memcpy(state->oldframes[c],state->oldframes[c+1],
sizeof(edict)*MAX_EDICTS);
state->oldframe_nums[c] = state->oldframe_nums[c+1];}
memcpy(state->oldframes[15],state->shared->edicts,
sizeof(edict)*MAX_EDICTS);
state->oldframe_nums[15] = state->frame_num;
}
//==============================================
void send_ack(protocol *state){
buffer *buf;
buf = newbuffer();
putLEu32(buf,state->seq);
putLEu32(buf,state->last_seq);
putLEu16(buf,state->qport);
sock_send(state->sock,buf);
freebuffer(buf);
state->seq++;
}
//==============================================
void parse_connected(protocol *state,buffer *buf,unsigned long seq){
state->last_seq = seq;
if ((seq & HIDDEN_BIT) || (getsize(buf) == 8))
send_ack(state);
proc_ack(state,getLEu32(buf));
parse_messages(state,buf);
}
//==============================================
void parse_packet(protocol *state,buffer *buf){
unsigned long seq;
seq = getLEu32(buf);
if (seq == 0xffffffff)
parse_connectionless(state,buf);
else
parse_connected(state,buf,seq);
}
//==============================================
void proc_need_ack(protocol *state){
double now;
if (state->need_ack ==
NULL) return;
now = gettime();
if ((now-state->need_ack_last) < state->shared->ping) return;
state->need_ack_last = now;
if
(state->need_ack->seq == 0)
state->need_ack->seq = state->seq;
bufsetppos(state->need_ack->buf,0);
putLEu32(state->need_ack->buf,HIDDEN_BIT | state->seq);
putLEu32(state->need_ack->buf,state->last_seq);
sock_send(state->sock,state->need_ack->buf);
state->seq++;
ping_start(state);
}
//==============================================
void proc_packet(protocol *state){
buffer *buf;
buf =
sock_recv(state->sock);
if (!buf) return;
parse_packet(state,buf);
freebuffer(buf);
}
//==============================================
void clear_data(protocol *state){
int c;
state->delta_frame = 0xffffffff;
for (c=0;c<16;c++)
state->oldframe_nums[c] = 0xffffffff;
memset(state->baseline,0,sizeof(edict)*MAX_EDICTS);
memset(state->shared->edicts,0,sizeof(edict)*MAX_EDICTS);
state->delta_angles = vec_mk(0.0,0.0,0.0);
}
//==============================================
void protocol_update(protocol *state){
switch(state->level){
case PRE_CHALLENGE:
send_getchallenge(state);
state->level = POST_CHALLENGE;
break;
case POST_CHALLENGE:
state->level = PRE_CHALLENGE;
break;
case PRE_CONNECT:
send_connect(state);
state->level = POST_CONNECT;
break;
case POST_CONNECT:
state->level = PRE_CONNECT;
break;
case POST_SYN:
clear_data(state);
protocol_send_console_command(state,"new\n");
state->level = PRE_GAME;
break;
case PRE_GAME: break;
case IN_GAME: break;
case POST_GAME:
protocol_send_console_command(state,"disconnect\n");
state->level = PRE_GAME_OVER;
break;
case PRE_GAME_OVER:
if (!state->need_ack) state->level = GAME_OVER;
break;
case GAME_OVER: break;
default:
printf(stderr,"internal error: unknown state\n");
exit(7);
} // switch
proc_need_ack(state);
proc_packet(state);
}
//==============================================
int protocol_getstate(protocol *state){
return (state->level-IN_GAME);
}
That's about all I can think of for this stuff..
If I come up with more,
I'll post..
Have Fun!
regards,
philip