(svn r214) -Feature: CMD_NET_INSTANT [just in time command handling over network] (sign_de)
authordarkvater
Sun, 12 Sep 2004 15:29:37 +0000
changeset 213 770e504a6e51
parent 212 0f38a4514384
child 214 f1ebbfefc3f8
(svn r214) -Feature: CMD_NET_INSTANT [just in time command handling over network] (sign_de)
-Fix: Only server can pause in network, action disabled for clients
-Fix: Direct Connect editbox can handle up to max ~35 characters
command.c
command.h
main_gui.c
network.c
network_gui.c
ttd.c
--- a/command.c	Sun Sep 12 14:20:43 2004 +0000
+++ b/command.c	Sun Sep 12 15:29:37 2004 +0000
@@ -445,9 +445,14 @@
 
 	// put the command in a network queue and execute it later?
 	if (_networking && !(cmd & CMD_DONT_NETWORK)) {
-		NetworkSendCommand(tile, p1, p2, cmd, callback);
-		_docommand_recursive = 0;
-		return true;
+		if (!(cmd & CMD_NET_INSTANT)) {
+			NetworkSendCommand(tile, p1, p2, cmd, callback);
+			_docommand_recursive = 0;
+			return true;
+		} else {
+			// Instant Command ... Relay and Process then
+			NetworkSendCommand(tile, p1, p2, cmd, callback);
+		}
 	}
 
 	// update last build coordinate of player.
--- a/command.h	Sun Sep 12 14:20:43 2004 +0000
+++ b/command.h	Sun Sep 12 15:29:37 2004 +0000
@@ -168,6 +168,7 @@
 	CMD_NO_WATER = 0x400,
 	CMD_DONT_NETWORK = 0x800,		// execute the command without sending it on the network
 	CMD_ASYNC = 0x1000,					// execute the command asynchronously without testing first in networking
+	CMD_NET_INSTANT = 0x2000,
 };
 
 //#define return_cmd_error(errcode) do { _error_message=(errcode); return CMD_ERROR; } while(0)
--- a/main_gui.c	Sun Sep 12 14:20:43 2004 +0000
+++ b/main_gui.c	Sun Sep 12 15:29:37 2004 +0000
@@ -83,7 +83,9 @@
 
 static void ToolbarPauseClick(Window *w)
 {
-	if (DoCommandP(0, _pause?0:1, 0, NULL, CMD_PAUSE))
+	if (_networking && !_networking_server) { return;} // only server can pause the game
+
+	if (DoCommandP(0, _pause?0:1, 0, NULL, CMD_PAUSE | CMD_NET_INSTANT))
 		SndPlayFx(0x13);
 }
 
@@ -1654,14 +1656,11 @@
 		GfxFillRect(0, 0, w->width-1, w->height-1, 0xB2);
 		GfxFillRect(0, 0, w->width-1, w->height-1, 0x80B4);
 
-		// if networking, disable fast-forward button
-		if (_networking) w->disabled_state |= (1 << 1);
-
 		// if spectator, disable things
 		if (_current_player == OWNER_SPECTATOR){
-			w->disabled_state |= (1 << 0) | (1 << 19) | (1<<20) | (1<<21) | (1<<22) | (1<<23);
+			w->disabled_state |= (1 << 19) | (1<<20) | (1<<21) | (1<<22) | (1<<23);
 		} else {
-			w->disabled_state &= ~((1 << 0) | (1 << 19) | (1<<20) | (1<<21) | (1<<22) | (1<<23));
+			w->disabled_state &= ~((1 << 19) | (1<<20) | (1<<21) | (1<<22) | (1<<23));
 		}
 
 		DrawWindowWidgets(w);
@@ -2225,7 +2224,14 @@
 		AssignWindowViewport(w, 0, 0, width, height, 0x8080, 0);
 
 		w = AllocateWindowDesc(&_toolb_normal_desc);
-		w->disabled_state = 1 << 17;
+		w->disabled_state = 1 << 17; // disable zoon-in button (by default game is zoomed in)
+
+		if (_networking) { // if networking, disable fast-forward button
+			w->disabled_state |= (1 << 1);
+			if (!_networking_server) // if not server, disable pause button
+				w->disabled_state |= (1 << 0);
+		}
+
 		w->flags4 &= ~WF_WHITE_BORDER_MASK;
 
 		PositionMainToolbar(w); // already WC_MAIN_TOOLBAR passed (&_toolb_normal_desc)
--- a/network.c	Sun Sep 12 14:20:43 2004 +0000
+++ b/network.c	Sun Sep 12 15:29:37 2004 +0000
@@ -235,6 +235,7 @@
 };
 
 void NetworkUDPSend(bool client, struct sockaddr_in recv,struct UDPPacket packet);
+static void HandleCommandPacket(ClientState *cs, CommandPacket *np);
 static void CloseClient(ClientState *cs);
 void NetworkSendWelcome(ClientState *cs, bool direct);
 
@@ -451,7 +452,11 @@
 	QueuedCommand *qp;
 	ClientState *cs;
 
-	qp = AllocQueuedCommand(_networking_server ? &_command_queue : &_ack_queue);
+	if (!(cmd & CMD_NET_INSTANT)) {
+		qp = AllocQueuedCommand(_networking_server ? &_command_queue : &_ack_queue);
+	} else {
+		qp = (QueuedCommand*)calloc(sizeof(QueuedCommand), 1);
+		}
 	qp->cp.packet_type = PACKET_TYPE_COMMAND;
 	qp->cp.tile = tile;
 	qp->cp.p1 = p1;
@@ -487,6 +492,9 @@
 	for(cs=_clients; cs->socket != INVALID_SOCKET; cs++) if (!cs->inactive) SendBytes(cs, &qp->cp, qp->cp.packet_length);
 
 #endif
+	if (cmd & CMD_NET_INSTANT) {
+		free(qp);
+	}
 }
 
 // client:
@@ -505,13 +513,22 @@
 	QueuedCommand *qp;
 	ClientState *c;
 	AckPacket ap;
+	uint16 cmd;
 
 	DEBUG(net, 2) ("[NET] cmd size %d", np->packet_length);
-
 	assert(np->packet_length >= COMMAND_PACKET_BASE_SIZE);
 
-	// put it into the command queue
-	qp = AllocQueuedCommand(&_command_queue);
+	cmd = np->cmd;
+#if defined(TTD_BIG_ENDIAN)
+	cmd = TO_LE16(cmd);
+#endif
+
+	if (!(cmd & CMD_NET_INSTANT)) {
+		// put it into the command queue
+		qp = AllocQueuedCommand(&_command_queue);
+	} else {
+		qp = (QueuedCommand*)calloc(sizeof(QueuedCommand), 1);
+	}
 	qp->cp = *np;
 	
 	qp->frame = _frame_counter_max - GetNextSyncFrame();
@@ -530,7 +547,7 @@
 	if (_networking_server) {
 		for(c=_clients; c->socket != INVALID_SOCKET; c++) {
 			if (c == cs) {
-				SendDirectBytes(c, &ap, ap.packet_length);
+				if (!(cmd & CMD_NET_INSTANT)) SendDirectBytes(c, &ap, ap.packet_length);
 			} else {
 				if (!cs->inactive) SendBytes(c, &qp->cp, qp->cp.packet_length);
 			}
@@ -546,6 +563,15 @@
 #endif
 
 	qp->cmd = qp->cp.cmd;
+
+	if (cmd & CMD_NET_INSTANT) {
+		byte p = _current_player;
+		_current_player = qp->cp.player;
+		memcpy(_decode_parameters, qp->cp.dp, (qp->cp.packet_length - COMMAND_PACKET_BASE_SIZE));
+		DoCommandP(qp->cp.tile, qp->cp.p1, qp->cp.p2, qp->callback, qp->cmd | CMD_DONT_NETWORK);
+		free(qp);
+		_current_player = p;
+		}
 }
 
 // sent from server -> client periodically to tell the client about the current tick in the server
--- a/network_gui.c	Sun Sep 12 14:20:43 2004 +0000
+++ b/network_gui.c	Sun Sep 12 15:29:37 2004 +0000
@@ -98,8 +98,8 @@
 				ShowQueryString(
 				str,
 				STR_NETWORK_ENTER_IP,
-				15,
-				160,
+				50,  // maximum 50 characters OR
+				250, // characters up to width 250 pixels, whichever is satisfied first
 				w->window_class,
 				w->window_number);
 				DeleteName(str);
--- a/ttd.c	Sun Sep 12 14:20:43 2004 +0000
+++ b/ttd.c	Sun Sep 12 15:29:37 2004 +0000
@@ -878,6 +878,9 @@
 // That check is enforced in DoCommand.
 void StateGameLoop()
 {
+	// dont execute the state loop during pause
+	if (_pause) return;
+
 	_in_state_game_loop = true;
 	_frame_counter++;
 
@@ -1021,8 +1024,7 @@
 		}
 	} else {
 		// server/client/standalone: not synced --> state game loop
-		if (!_pause)
-			StateGameLoop();
+		StateGameLoop();
 		// server/client: process queued network commands
 		if (_networking) NetworkProcessCommands();
 	}