(svn r240) -Fix: desync on subsidy generation
authorsignde
Mon, 13 Sep 2004 22:49:11 +0000
changeset 239 23958632a582
parent 238 a73a3e50c7f9
child 240 f1efbac04112
(svn r240) -Fix: desync on subsidy generation
-Fix: sometimes commands got executed to early on some clients
-Feature: universal event packets for transmitting subsidys
economy.c
economy.h
functions.h
macros.h
misc.c
network.c
network.h
ttd.c
--- a/economy.c	Mon Sep 13 22:04:20 2004 +0000
+++ b/economy.c	Mon Sep 13 22:49:11 2004 +0000
@@ -11,6 +11,7 @@
 #include "economy.h"
 #include "industry.h"
 #include "town.h"
+#include "network.h"
 
 void UpdatePlayerHouse(Player *p, uint score)
 {
@@ -807,11 +808,11 @@
 
 	fr->distance = (uint)-1;
 
-	fr->from = from = DEREF_TOWN(RandomRange(_total_towns));
+	fr->from = from = DEREF_TOWN(InteractiveRandomRange(_total_towns));
 	if (from->xy == 0 || from->population < 400)
 		return;
 
-	fr->to = to = DEREF_TOWN(RandomRange(_total_towns));
+	fr->to = to = DEREF_TOWN(InteractiveRandomRange(_total_towns));
 	if (from==to || to->xy == 0 || to->population < 400 || to->pct_pass_transported > 42)
 		return;
 
@@ -826,12 +827,12 @@
 
 	fr->distance = (uint)-1;
 
-	fr->from = i = DEREF_INDUSTRY(RandomRange(_total_industries));
+	fr->from = i = DEREF_INDUSTRY(InteractiveRandomRange(_total_industries));
 	if (i->xy == 0)
 		return;
 
 	// Randomize cargo type
-	if (Random()&1 && i->produced_cargo[1] != 0xFF) {
+	if (InteractiveRandom()&1 && i->produced_cargo[1] != 0xFF) {
 		cargo = i->produced_cargo[1];
 		trans = i->pct_transported[1];
 		total = i->total_production[1];
@@ -851,7 +852,7 @@
 
 	if (cargo == CT_GOODS || cargo == CT_FOOD) {
 		// The destination is a town
-		Town *t = DEREF_TOWN(RandomRange(_total_towns));
+		Town *t = DEREF_TOWN(InteractiveRandomRange(_total_towns));
 
 		// Only want big towns
 		if (t->xy == 0 || t->population < 900)
@@ -860,7 +861,7 @@
 		fr->to = t;
 	} else {
 		// The destination is an industry
-		Industry *i2 = DEREF_INDUSTRY(RandomRange(_total_industries));
+		Industry *i2 = DEREF_INDUSTRY(InteractiveRandomRange(_total_industries));
 
 		// The industry must accept the cargo
 		if (i == i2 || i2->xy == 0 ||
@@ -890,6 +891,25 @@
 	return false;
 }
 
+void RemoteSubsidyAdd(Subsidy *s_new)
+{
+	Subsidy *s;
+	Pair pair;
+
+	// search the first free subsidy
+	for(s=_subsidies; s != endof(_subsidies); s++) 
+		if (s->cargo_type == 0xFF)
+			break;
+
+	memcpy(s,s_new,sizeof(Subsidy));
+
+	pair = SetupSubsidyDecodeParam(s, 0);
+	AddNewsItem(STR_2030_SERVICE_SUBSIDY_OFFERED, NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_SUBSIDIES, 0), pair.a, pair.b);
+
+	InvalidateWindow(WC_SUBSIDIES_LIST, 0);
+
+}
+
 static void SubsidyMonthlyHandler()
 {
 	Subsidy *s;
@@ -921,8 +941,10 @@
 		}
 	}
 
+	if ((_networking) && (!_networking_server)) return;
+
 	// 25% chance to go on
-	if (CHANCE16(1,4)) {
+	if (ICHANCE16(1,4)) {
 		// Find a free slot
 		s = _subsidies;
 		while (s->cargo_type != 0xFF) {
@@ -948,12 +970,13 @@
 				if (!CheckSubsidyDuplicate(s)) {
 					s->age = 0;
 					pair = SetupSubsidyDecodeParam(s, 0);
+					if (_networking_server) NetworkSendEvent(NET_EVENT_SUBSIDY,sizeof(Subsidy),s);
 					AddNewsItem(STR_2030_SERVICE_SUBSIDY_OFFERED, NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_SUBSIDIES, 0), pair.a, pair.b);
 					modified = true;
 					break;
 				}
 			}
-		} while (--n);
+		} while (n--);
 	}
 no_add:;
 	if (modified)
--- a/economy.h	Mon Sep 13 22:04:20 2004 +0000
+++ b/economy.h	Mon Sep 13 22:49:11 2004 +0000
@@ -70,6 +70,7 @@
 Pair SetupSubsidyDecodeParam(Subsidy *s, bool mode);
 void DeleteSubsidyWithIndustry(byte index);
 void DeleteSubsidyWithStation(byte index);
+void RemoteSubsidyAdd(Subsidy *s_new); 
 
 int32 GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, byte cargo_type);
 uint MoveGoodsToStation(uint tile, int w, int h, int type, uint amount);
--- a/functions.h	Mon Sep 13 22:04:20 2004 +0000
+++ b/functions.h	Mon Sep 13 22:49:11 2004 +0000
@@ -100,6 +100,8 @@
 void InitPlayerRandoms();
 
 uint32 InteractiveRandom(); /* Used for random sequences that are not the same on the other end of the multiplayer link */
+uint InteractiveRandomRange(uint max);
+
 void SetDate(uint date);
 /* facedraw.c */
 void DrawPlayerFace(uint32 face, int color, int x, int y);
@@ -132,6 +134,7 @@
 void NetworkInitialize();
 void NetworkShutdown();
 void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback);
+void NetworkSendEvent(uint16 type, uint16 data_len, void * data);
 void NetworkStartSync(bool fcreset);
 void NetworkClose(bool client);
 void NetworkSendReadyPacket();
--- a/macros.h	Mon Sep 13 22:04:20 2004 +0000
+++ b/macros.h	Mon Sep 13 22:49:11 2004 +0000
@@ -170,6 +170,7 @@
 
 
 #define CHANCE16(a,b) ((uint16)Random() <= (uint16)((65536 * a) / b))
+#define ICHANCE16(a,b) ((uint16)InteractiveRandom() <= (uint16)((65536 * a) / b))
 #define CHANCE16R(a,b,r) ((uint16)(r=Random()) <= (uint16)((65536 * a) / b))
 #define CHANCE16I(a,b,v) ((uint16)(v) <= (uint16)((65536 * a) / b))
 
--- a/misc.c	Mon Sep 13 22:04:20 2004 +0000
+++ b/misc.c	Mon Sep 13 22:49:11 2004 +0000
@@ -44,6 +44,11 @@
 	return _random_seeds[1][1] = ROR(s, 3);
 }
 
+uint InteractiveRandomRange(uint max)
+{
+	return (uint16)InteractiveRandom() * max >> 16;
+}
+
 void InitPlayerRandoms()
 {
 	int i;
--- a/network.c	Mon Sep 13 22:04:20 2004 +0000
+++ b/network.c	Mon Sep 13 22:49:11 2004 +0000
@@ -4,6 +4,7 @@
 #include "command.h"
 #include "player.h"
 #include "console.h"
+#include "economy.h"
 
 #if defined(WIN32)
 #	include <windows.h>
@@ -87,6 +88,7 @@
 	PACKET_TYPE_FSYNC,
 	PACKET_TYPE_XMIT,
 	PACKET_TYPE_COMMAND,
+	PACKET_TYPE_EVENT,
 };
 
 // sent from client -> server whenever the client wants to exec a command.
@@ -102,6 +104,13 @@
 	uint32 dp[8];
 } CommandPacket;
 
+typedef struct EventPacket {
+	byte packet_length;
+	byte packet_type;
+	byte event_type;
+	byte data_start;
+} EventPacket;
+
 #define COMMAND_PACKET_BASE_SIZE (sizeof(CommandPacket) - 8 * sizeof(uint32))
 
 // sent from server -> client periodically to tell the client about the current tick in the server
@@ -343,9 +352,9 @@
 static int GetNextSyncFrame()
 {
 	uint32 newframe;
-	if (_frame_fsync_last == 0) return -1;
-	newframe = (_frame_fsync_last + 9);
-	if ( (newframe + 4) > _frame_counter_max) return -1;
+	if (_frame_fsync_last == 0) return -5;
+	newframe = (_frame_fsync_last + 16);
+	if ( (newframe + 4) > _frame_counter_max) return -5;
 	return (_frame_counter_max - newframe);
 
 }
@@ -367,7 +376,7 @@
 		if (!(nq->head = qp->next)) nq->last = &nq->head;
 
 		if (qp->frame < _frame_counter && _networking_sync) {
-			DEBUG(net,0) ("error: !qp->cp.frame < _frame_counter, %d < %d\n", qp->frame, _frame_counter);
+			DEBUG(net,0) ("warning: !qp->cp.frame < _frame_counter, %d < %d [%d]\n", qp->frame, _frame_counter, _frame_counter_srv+4);
 		}
 
 		// run the command
@@ -495,6 +504,25 @@
 	}
 }
 
+void NetworkSendEvent(uint16 type, uint16 data_len, void * data)
+{
+	EventPacket * ep;
+	ClientState *cs;
+	
+	// encode the event ... add its data
+	ep=malloc(data_len+sizeof(EventPacket)-1);
+	ep->event_type = type;
+	ep->packet_length = data_len+sizeof(EventPacket)-1;
+	ep->packet_type = PACKET_TYPE_EVENT;
+	memcpy(&ep->data_start,data,data_len);
+
+	// send it to the peers
+	for(cs=_clients; cs->socket != INVALID_SOCKET; cs++) if (!cs->inactive) SendBytes(cs, ep, ep->packet_length);
+
+	// free the temp packet
+	free(ep);
+}
+
 // client:
 //   server sends a command from another player that we should execute.
 //   put it in the command queue.
@@ -572,6 +600,15 @@
 		}
 }
 
+static void HandleEventPacket(EventPacket *ep)
+{
+	switch (ep->event_type) {
+		case NET_EVENT_SUBSIDY:
+			RemoteSubsidyAdd((Subsidy *)&ep->data_start);
+			break;
+	}
+}
+
 // sent from server -> client periodically to tell the client about the current tick in the server
 // and how far the client may progress.
 static void HandleSyncPacket(SyncPacket *sp)
@@ -785,6 +822,9 @@
 			case PACKET_TYPE_READY:
 				HandleReadyPacket((ReadyPacket*)packet, cs);
 				break;
+			case PACKET_TYPE_EVENT:
+				HandleEventPacket((EventPacket*)packet);
+				break;
 			default:
 				DEBUG (net,0) ("net: unknown packet type");
 			}
@@ -1907,6 +1947,7 @@
 void NetworkReceive() {}
 void NetworkSend() {}
 void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback) {}
+void NetworkSendEvent(uint16 type, uint16 data_len, void * data) {};
 void NetworkProcessCommands() {}
 void NetworkStartSync(bool fcreset) {}
 void NetworkSendReadyPacket() {}
--- a/network.h	Mon Sep 13 22:04:20 2004 +0000
+++ b/network.h	Mon Sep 13 22:49:11 2004 +0000
@@ -24,6 +24,10 @@
 	struct NetworkGameList * _next;
 } NetworkGameList;
 
+enum {
+	NET_EVENT_SUBSIDY = 0,
+};
+
 NetworkGameInfo _network_game;
 NetworkGameList * _network_game_list;
 
--- a/ttd.c	Mon Sep 13 22:04:20 2004 +0000
+++ b/ttd.c	Mon Sep 13 22:49:11 2004 +0000
@@ -889,7 +889,7 @@
 	// store the random seed to be able to detect out of sync errors
 	_sync_seed_1 = _random_seeds[0][0];
 	_sync_seed_2 = _random_seeds[0][1];
-	if (_networking) disable_computer=true;
+ 	if (_networking) disable_computer=true;
 
 	if (_savedump_path[0] && (uint)_frame_counter >= _savedump_first && (uint)(_frame_counter -_savedump_first) % _savedump_freq == 0 ) {
 		char buf[100];