(svn r266) -Fix: hopefully fixed the desync problem nicely (and reverted the

workaround for it)
This commit is contained in:
truelight 2004-09-15 18:36:33 +00:00
parent 0346fec1ca
commit a69e422cdd
5 changed files with 28 additions and 9 deletions

View File

@ -1208,10 +1208,12 @@ int LoadUnloadVehicle(Vehicle *v)
GoodsEntry *ge;
int t;
uint count, cap;
byte old_player;
assert((v->next_order&0x1F) == OT_LOADING);
v->cur_speed = 0;
old_player = _current_player;
_current_player = v->owner;
st = DEREF_STATION(last_visited = v->last_station_visited);
@ -1318,6 +1320,7 @@ next_vehicle:;
}
}
_current_player = old_player;
return result;
}

19
misc.c
View File

@ -15,15 +15,20 @@ static INLINE uint32 ROR(uint32 x, int n)
return (x >> n) + (x << ((sizeof(x)*8)-n));
}
/* Fuck bitch code, most probably one of the loops (tileloop, vehicleloop, etc.)
* doesn't set up/reset _current_player so the normal random below fails #$%@$#!
* The old code below is prune to desyncs because randoms interfere.
* SO FIND THE OFFENDING LOOP AND FIX IT ONCE AND FOR ALL */
#undef NORMAL_RANDOM // unuseable game, desyncs way too fast
// For multiplayer, we introduced this new way of random-seeds
// It is player-based, so 2 clients can do 2 commands at the same time
// without the game desyncing.
// It is not used for non-multiplayer games
#ifdef ENABLE_NETWORK
#define PLAYER_SEED_RANDOM
#else
#undef PLAYER_SEED_RANDOM
#endif
uint32 Random()
{
#ifdef NORMAL_RANDOM
if (_current_player>=MAX_PLAYERS) {
#ifdef PLAYER_SEED_RANDOM
if (_current_player>=MAX_PLAYERS || !_networking) {
uint32 s = _random_seeds[0][0];
uint32 t = _random_seeds[0][1];
_random_seeds[0][0] = s + ROR(t ^ 0x1234567F, 7);

View File

@ -365,6 +365,7 @@ void NetworkProcessCommands()
{
CommandQueue *nq;
QueuedCommand *qp;
byte old_player;
// queue mode ?
if (_networking_queuing)
@ -380,11 +381,13 @@ void NetworkProcessCommands()
}
// run the command
old_player = _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 = old_player;
}
if (!_networking_server) {
@ -508,7 +511,7 @@ 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;

View File

@ -694,6 +694,7 @@ bool GrowTown(Town *t)
const TileIndexDiff *ptr;
int offs;
TileInfo ti;
byte old_player;
static const TileIndexDiff _town_coord_mod[] = {
TILE_XY(-1,0),
@ -712,6 +713,7 @@ bool GrowTown(Town *t)
};
// Current player is a town
old_player = _current_player;
_current_player = OWNER_TOWN;
// Find a road that we can base the construction on.
@ -719,7 +721,9 @@ bool GrowTown(Town *t)
ptr = _town_coord_mod;
do {
if (GetRoadBitsByTile(tile) != 0) {
return GrowTownAtRoad(t, tile);
int r = GrowTownAtRoad(t, tile);
_current_player = old_player;
return r;
}
offs = *ptr++;
@ -737,6 +741,7 @@ bool GrowTown(Town *t)
if (ti.tileh == 0 && !(ti.type==MP_HOUSE && ti.map5==0)) {
if (DoCommandByTile(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR) != CMD_ERROR) {
DoCommandByTile(tile, GenRandomRoadBits(), 0, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD);
_current_player = old_player;
return true;
}
}
@ -744,6 +749,7 @@ bool GrowTown(Town *t)
tile = TILE_ADD(tile, offs);
} while (offs != 0);
_current_player = old_player;
return false;
}

View File

@ -1378,6 +1378,8 @@ void MaybeRenewVehicle(Vehicle *v, int32 build_cost)
v->value = build_cost;
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
_current_player = OWNER_NONE;
}