Skip to content

Commit

Permalink
Loading new maps in multiplayer now (mostly) works
Browse files Browse the repository at this point in the history
Fix failed connection bug (not super sure why this is happening to start
  with, but this hack works for now)
  • Loading branch information
camgunz committed Feb 15, 2017
1 parent 1d806b8 commit 49d9bed
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 35 deletions.
13 changes: 3 additions & 10 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,10 @@
crash

1. Fix bugs:
- Some races around game state: clients are in intermission, then level, then
intermission again when loading a new map
- `G_DoLoadLevel`
- `...`
- `G_WorldDone`
- `G_DoLoadLevel`
- Connection sometimes takes multiple tries
- Sometimes the server doesn't call `G_WorldDone` when `gameaction` is set to
`ga_worlddone`; something sets it back to `ga_nothing` first.
- Nothing displays in console
- Probably scripting bug
- Should fix silently failing scripting... then again that probably goes to
the console to haha
- Checked, (probably) not a scripting bug
- Console and messages widget should render during intermission
- I think widgets need a "render during intermission" flag
- Windows crashes pretty early on
Expand Down
4 changes: 4 additions & 0 deletions src/cl_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,10 @@ bool CL_RePredicting(void) {
return (CLIENT && cl_repredicting);
}

void CL_SetNeedsInitNew(void) {
cl_needs_init_new = true;
}

void CL_ResetSync(void) {
netpeer_t *server = CL_GetServerPeer();

Expand Down
1 change: 1 addition & 0 deletions src/cl_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ bool CL_OccurredDuringRePrediction(int tic);
bool CL_LoadingState(void);
bool CL_Synchronizing(void);
bool CL_RePredicting(void);
void CL_SetNeedsInitNew(void);
void CL_ResetSync(void);

#endif
Expand Down
6 changes: 6 additions & 0 deletions src/d_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ void D_Msg(msg_channel_e chan, const char *fmt, ...) {
va_list args;
va_list log_args;
va_list console_args;
va_list cmdline_args;
message_channel_t *mc;

check_message_channel(chan);
Expand Down Expand Up @@ -202,6 +203,11 @@ void D_Msg(msg_channel_e chan, const char *fmt, ...) {
fflush(mc->fobj);
}

va_copy(cmdline_args, args);
vprintf(fmt, cmdline_args);
va_end(cmdline_args);
fflush(stdout);

va_end(args);
}

Expand Down
44 changes: 42 additions & 2 deletions src/g_game.c
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,7 @@ void G_RestartLevel(void) {
// G_DoLoadLevel
//

static void G_DoLoadLevel(void) {
void G_DoLoadLevel(void) {
int i;

if (CLIENT) {
Expand Down Expand Up @@ -1473,8 +1473,9 @@ void G_Ticker(void) {
switch (gameaction) {
case ga_loadlevel:
// force players to be initialized on level reload
for (i = 0; i < MAXPLAYERS; i++)
for (i = 0; i < MAXPLAYERS; i++) {
players[i].playerstate = PST_REBORN;
}

G_DoLoadLevel();
break;
Expand Down Expand Up @@ -4029,8 +4030,47 @@ gameaction_t G_GetGameAction(void) {
}

void G_SetGameAction(gameaction_t new_gameaction) {
if (CLIENT) {
if (new_gameaction == ga_nothing) {
gameaction = ga_nothing;
}
return;
}

gameaction = new_gameaction;

#if 0
switch (new_gameaction) {
case ga_nothing:
puts("ga_nothing");
break;
case ga_loadlevel:
puts("ga_loadlevel");
break;
case ga_newgame:
puts("ga_newgame");
break;
case ga_loadgame:
puts("ga_loadgame");
break;
case ga_savegame:
puts("ga_savegame");
break;
case ga_playdemo:
puts("ga_playdemo");
break;
case ga_completed:
puts("ga_completed");
break;
case ga_victory:
puts("ga_victory");
break;
case ga_worlddone:
puts("ga_worlddone");
break;
}
#endif

if (SERVER && gameaction != ga_nothing) {
SV_BroadcastGameActionChange();
}
Expand Down
1 change: 1 addition & 0 deletions src/g_game.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ void G_DoReborn(int playernum);
void G_DoPlayDemo(void);
void G_DoCompleted(void);
void G_DoWorldDone(void);
void G_DoLoadLevel(void);
void G_Compatibility(void);
void G_ReadOptions(unsigned char game_options[]);
void G_WriteOptions(unsigned char game_options[]);
Expand Down
37 changes: 26 additions & 11 deletions src/n_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ static bool should_render(void) {

void N_InitNetGame(void) {
int i;
time_t start_request_time;

netgame = false;
solonet = false;
Expand Down Expand Up @@ -210,22 +211,36 @@ void N_InitNetGame(void) {
"N_InitNetGame: Connecting to server %s:%u...\n", host, port
);

if (!N_Connect(host, port)) {
I_Error("N_InitNetGame: Connection refused");
}
for (int i = 0; i < MAX_SETUP_REQUEST_ATTEMPTS; i++) {
if (!N_Connect(host, port)) {
I_Error("N_InitNetGame: Connection refused");
}

D_Msg(MSG_INFO, "N_InitNetGame: Connected!\n");
D_Msg(MSG_INFO, "N_InitNetGame: Connected!\n");

if (!CL_GetServerPeer()) {
I_Error("N_InitNetGame: Server peer was NULL");
}
if (!CL_GetServerPeer()) {
I_Error("N_InitNetGame: Server peer was NULL");
}

G_ReloadDefaults();
G_ReloadDefaults();

for (size_t i = 1; i <= MAX_SETUP_REQUEST_ATTEMPTS; i++) {
D_Msg(MSG_INFO, "N_InitNetGame: Requesting setup information...\n");
CL_SendSetupRequest();
N_ServiceNetworkTimeout(1000);

start_request_time = time(NULL);

while (N_Connected()) {
CL_SendSetupRequest();
N_ServiceNetwork();

if (CL_ReceivedSetup()) {
break;
}

if (difftime(time(NULL), start_request_time) > 10.0) {
break;
}
}

if (CL_ReceivedSetup()) {
break;
}
Expand Down
1 change: 1 addition & 0 deletions src/n_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ void N_Disconnect(void);
void N_Shutdown(void);
bool N_Listen(const char *host, uint16_t port);
bool N_Connect(const char *host, uint16_t port);
bool N_Connected(void);
bool N_Reconnect(void);
bool N_ConnectToServer(const char *address);
void N_DisconnectPeer(netpeer_t *np);
Expand Down
7 changes: 4 additions & 3 deletions src/n_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,13 @@ bool N_Connect(const char *host, uint16_t port) {
previous_host = host;
previous_port = port;

D_Msg(MSG_INFO, "N_Connect: connected");

return true;
}

bool N_Connected(void) {
return (net_host != NULL);
}

bool N_Reconnect(void) {
if ((!previous_host) || (previous_port == 0)) {
D_Msg(MSG_INFO, "No previous connection\n");
Expand Down Expand Up @@ -301,7 +303,6 @@ static void handle_enet_disconnection(ENetEvent *net_event) {

if (CLIENT) {
N_Disconnect();
I_SafeExit(0);
}

N_PeerRemove(np);
Expand Down
7 changes: 0 additions & 7 deletions src/n_pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -801,8 +801,6 @@ void N_PackSync(netpeer_t *np) {

M_PBufWriteULong(pbuf, bitmap);

M_PBufWriteInt(pbuf, G_GetGameState());

NETPEER_FOR_EACH(iter) {
unsigned int playernum = N_PeerGetPlayernum(iter.np);

Expand Down Expand Up @@ -839,14 +837,9 @@ bool N_UnpackSync(netpeer_t *np) {
read_ulong(pbuf, m_bitmap, "sync player bitmap");

if (CLIENT) {
gamestate_t m_gamestate;
int m_delta_from_tic;
int m_delta_to_tic;

read_int(pbuf, m_gamestate, "game state");

CL_SetNewGameState(m_gamestate);

for (int i = 0; i < MAXPLAYERS; i++) {
if ((m_bitmap & (1 << i)) == 0) {
continue;
Expand Down
24 changes: 22 additions & 2 deletions src/n_proto.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ static void handle_setup_request(netpeer_t *np) {
static void handle_full_state(netpeer_t *np) {
N_UnpackFullState(np);
N_PeerSyncSetHasGameState(np);
CL_SetNewGameState(GS_LEVEL);
}

static void handle_auth_response(netpeer_t *np) {
Expand Down Expand Up @@ -457,8 +456,29 @@ static void handle_game_action_change(netpeer_t *np) {
return;
}

G_SetGameAction(new_gameaction);
gametic = new_gametic;

switch (new_gameaction) {
case ga_loadlevel:
puts("got ga_loadlevel");
// force players to be initialized on level reload
for (size_t i = 0; i < MAXPLAYERS; i++) {
players[i].playerstate = PST_REBORN;
}

G_DoLoadLevel();
break;
case ga_completed:
puts("got ga_completed");
G_DoCompleted();
break;
case ga_worlddone:
puts("got ga_worlddone");
G_DoWorldDone();
break;
default:
break;
}
}

static void handle_rcon(netpeer_t *np) {
Expand Down

0 comments on commit 49d9bed

Please sign in to comment.