mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r18046) [0.7] -Backport from trunk:
- Fix: AIs failed to load their data from savegames by crashing them when they tried [FS#3290] (r18038) - Fix: Screen jumped a bit for at least SDL and Allegro when right-click-dragging (r18030) - Fix: [NewGRF] Improve parsing of RIFF data. Skip unknown chunks and check chunk sizes (r17999) - Fix: Count only active clients (not those waiting for map download) when checking min_active_clients limit (r16506)
This commit is contained in:
parent
e4b45169c1
commit
b4ba357017
|
@ -330,14 +330,20 @@ StringID GetNetworkErrorMsg(NetworkErrorCode err)
|
||||||
return network_error_strings[err];
|
return network_error_strings[err];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Count the number of active clients connected */
|
/**
|
||||||
|
* Counts the number of active clients connected.
|
||||||
|
* It has to be in STATUS_ACTIVE and not a spectator
|
||||||
|
* @return number of active clients
|
||||||
|
*/
|
||||||
static uint NetworkCountActiveClients()
|
static uint NetworkCountActiveClients()
|
||||||
{
|
{
|
||||||
const NetworkClientInfo *ci;
|
const NetworkClientSocket *cs;
|
||||||
uint count = 0;
|
uint count = 0;
|
||||||
|
|
||||||
FOR_ALL_CLIENT_INFOS(ci) {
|
FOR_ALL_CLIENT_SOCKETS(cs) {
|
||||||
if (IsValidCompanyID(ci->client_playas)) count++;
|
if (cs->status != STATUS_ACTIVE) continue;
|
||||||
|
if (!IsValidCompanyID(cs->GetInfo()->client_playas)) continue;
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "map_func.h"
|
#include "map_func.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "core/alloc_type.hpp"
|
#include "core/alloc_type.hpp"
|
||||||
|
#include "core/mem_func.hpp"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "table/build_industry.h"
|
#include "table/build_industry.h"
|
||||||
|
@ -5150,7 +5151,7 @@ static void GRFImportBlock(byte *buf, int len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LoadGRFSound(byte *buf, int len)
|
static void LoadGRFSound(byte *buf, uint len)
|
||||||
{
|
{
|
||||||
byte *buf_start = buf;
|
byte *buf_start = buf;
|
||||||
|
|
||||||
|
@ -5163,22 +5164,31 @@ static void LoadGRFSound(byte *buf, int len)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Size of file -- we ignore this */
|
uint32 total_size = grf_load_dword(&buf);
|
||||||
grf_load_dword(&buf);
|
if (total_size > len + 8) {
|
||||||
|
grfmsg(1, "LoadGRFSound: RIFF was truncated");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (grf_load_dword(&buf) != BSWAP32('WAVE')) {
|
if (grf_load_dword(&buf) != BSWAP32('WAVE')) {
|
||||||
grfmsg(1, "LoadGRFSound: Invalid RIFF type");
|
grfmsg(1, "LoadGRFSound: Invalid RIFF type");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
while (total_size >= 8) {
|
||||||
uint32 tag = grf_load_dword(&buf);
|
uint32 tag = grf_load_dword(&buf);
|
||||||
uint32 size = grf_load_dword(&buf);
|
uint32 size = grf_load_dword(&buf);
|
||||||
|
total_size -= 8;
|
||||||
|
if (total_size < size) {
|
||||||
|
grfmsg(1, "LoadGRFSound: Invalid RIFF");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
total_size -= size;
|
||||||
|
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case ' tmf': // 'fmt '
|
case ' tmf': // 'fmt '
|
||||||
/* Audio format, must be 1 (PCM) */
|
/* Audio format, must be 1 (PCM) */
|
||||||
if (grf_load_word(&buf) != 1) {
|
if (size < 16 || grf_load_word(&buf) != 1) {
|
||||||
grfmsg(1, "LoadGRFSound: Invalid audio format");
|
grfmsg(1, "LoadGRFSound: Invalid audio format");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5188,13 +5198,13 @@ static void LoadGRFSound(byte *buf, int len)
|
||||||
grf_load_word(&buf);
|
grf_load_word(&buf);
|
||||||
se->bits_per_sample = grf_load_word(&buf);
|
se->bits_per_sample = grf_load_word(&buf);
|
||||||
|
|
||||||
/* Consume any extra bytes */
|
/* The rest will be skipped */
|
||||||
for (; size > 16; size--) grf_load_byte(&buf);
|
size -= 16;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'atad': // 'data'
|
case 'atad': // 'data'
|
||||||
se->file_size = size;
|
se->file_size = size;
|
||||||
se->file_offset = FioGetPos() - (len - (buf - buf_start)) + 1;
|
se->file_offset = FioGetPos() - (len - (buf - buf_start));
|
||||||
se->file_slot = _file_index;
|
se->file_slot = _file_index;
|
||||||
|
|
||||||
/* Set default volume and priority */
|
/* Set default volume and priority */
|
||||||
|
@ -5202,13 +5212,21 @@ static void LoadGRFSound(byte *buf, int len)
|
||||||
se->priority = 0;
|
se->priority = 0;
|
||||||
|
|
||||||
grfmsg(2, "LoadGRFSound: channels %u, sample rate %u, bits per sample %u, length %u", se->channels, se->rate, se->bits_per_sample, size);
|
grfmsg(2, "LoadGRFSound: channels %u, sample rate %u, bits per sample %u, length %u", se->channels, se->rate, se->bits_per_sample, size);
|
||||||
return;
|
return; // the fmt chunk has to appear before data, so we are finished
|
||||||
|
|
||||||
default:
|
default:
|
||||||
se->file_size = 0;
|
/* Skip unknown chunks */
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Skip rest of chunk */
|
||||||
|
for (; size > 0; size--) grf_load_byte(&buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grfmsg(1, "LoadGRFSound: RIFF does not contain any sound data");
|
||||||
|
|
||||||
|
/* Clear everything that was read */
|
||||||
|
MemSetT(se, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Action 0x12 */
|
/* Action 0x12 */
|
||||||
|
@ -5347,22 +5365,34 @@ static void TranslateGRFStrings(byte *buf, size_t len)
|
||||||
/* 'Action 0xFF' */
|
/* 'Action 0xFF' */
|
||||||
static void GRFDataBlock(byte *buf, int len)
|
static void GRFDataBlock(byte *buf, int len)
|
||||||
{
|
{
|
||||||
|
/* <FF> <name_len> <name> '\0' <data> */
|
||||||
|
|
||||||
if (_grf_data_blocks == 0) {
|
if (_grf_data_blocks == 0) {
|
||||||
grfmsg(2, "GRFDataBlock: unexpected data block, skipping");
|
grfmsg(2, "GRFDataBlock: unexpected data block, skipping");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!check_length(len, 3, "GRFDataBlock")) return;
|
||||||
|
|
||||||
buf++;
|
buf++;
|
||||||
uint8 name_len = grf_load_byte(&buf);
|
uint8 name_len = grf_load_byte(&buf);
|
||||||
const char *name = (const char *)buf;
|
const char *name = (const char *)buf;
|
||||||
buf += name_len + 1;
|
buf += name_len;
|
||||||
|
|
||||||
|
/* Test string termination */
|
||||||
|
if (grf_load_byte(&buf) != 0) {
|
||||||
|
grfmsg(2, "GRFDataBlock: Name not properly terminated");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!check_length(len, 3 + name_len, "GRFDataBlock")) return;
|
||||||
|
|
||||||
grfmsg(2, "GRFDataBlock: block name '%s'...", name);
|
grfmsg(2, "GRFDataBlock: block name '%s'...", name);
|
||||||
|
|
||||||
_grf_data_blocks--;
|
_grf_data_blocks--;
|
||||||
|
|
||||||
switch (_grf_data_type) {
|
switch (_grf_data_type) {
|
||||||
case GDT_SOUND: LoadGRFSound(buf, len - name_len - 2); break;
|
case GDT_SOUND: LoadGRFSound(buf, len - name_len - 3); break;
|
||||||
default: NOT_REACHED(); break;
|
default: NOT_REACHED(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,7 +222,7 @@ bool Squirrel::CallMethod(HSQOBJECT instance, const char *method_name, HSQOBJECT
|
||||||
if (ret != NULL) sq_getstackobj(vm, -1, ret);
|
if (ret != NULL) sq_getstackobj(vm, -1, ret);
|
||||||
/* Reset the top, but don't do so for the AI main function, as we need
|
/* Reset the top, but don't do so for the AI main function, as we need
|
||||||
* a correct stack when resuming. */
|
* a correct stack when resuming. */
|
||||||
if (suspend == -1) sq_settop(this->vm, top);
|
if (suspend == -1 || !this->IsSuspended()) sq_settop(this->vm, top);
|
||||||
/* Restore the return-value location. */
|
/* Restore the return-value location. */
|
||||||
this->vm->_suspended_target = last_target;
|
this->vm->_suspended_target = last_target;
|
||||||
|
|
||||||
|
|
|
@ -981,8 +981,6 @@ public:
|
||||||
if (widget == SM_WIDGET_MAP) {
|
if (widget == SM_WIDGET_MAP) {
|
||||||
if (_scrolling_viewport) return;
|
if (_scrolling_viewport) return;
|
||||||
_scrolling_viewport = true;
|
_scrolling_viewport = true;
|
||||||
_cursor.delta.x = 0;
|
|
||||||
_cursor.delta.y = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -368,8 +368,8 @@ static void PollEvent()
|
||||||
int dy = mouse_y - _cursor.pos.y;
|
int dy = mouse_y - _cursor.pos.y;
|
||||||
if (dx != 0 || dy != 0) {
|
if (dx != 0 || dy != 0) {
|
||||||
if (_cursor.fix_at) {
|
if (_cursor.fix_at) {
|
||||||
_cursor.delta.x += dx;
|
_cursor.delta.x = dx;
|
||||||
_cursor.delta.y += dy;
|
_cursor.delta.y = dy;
|
||||||
position_mouse(_cursor.pos.x, _cursor.pos.y);
|
position_mouse(_cursor.pos.x, _cursor.pos.y);
|
||||||
} else {
|
} else {
|
||||||
_cursor.delta.x = dx;
|
_cursor.delta.x = dx;
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
|
|
||||||
class FVideoDriver_Allegro: public VideoDriverFactory<FVideoDriver_Allegro> {
|
class FVideoDriver_Allegro: public VideoDriverFactory<FVideoDriver_Allegro> {
|
||||||
public:
|
public:
|
||||||
static const int priority = 5;
|
static const int priority = 4;
|
||||||
/* virtual */ const char *GetName() { return "allegro"; }
|
/* virtual */ const char *GetName() { return "allegro"; }
|
||||||
/* virtual */ const char *GetDescription() { return "Allegro Video Driver"; }
|
/* virtual */ const char *GetDescription() { return "Allegro Video Driver"; }
|
||||||
/* virtual */ Driver *CreateInstance() { return new VideoDriver_Allegro(); }
|
/* virtual */ Driver *CreateInstance() { return new VideoDriver_Allegro(); }
|
||||||
|
|
|
@ -334,8 +334,8 @@ static int PollEvent()
|
||||||
int dx = ev.motion.x - _cursor.pos.x;
|
int dx = ev.motion.x - _cursor.pos.x;
|
||||||
int dy = ev.motion.y - _cursor.pos.y;
|
int dy = ev.motion.y - _cursor.pos.y;
|
||||||
if (dx != 0 || dy != 0) {
|
if (dx != 0 || dy != 0) {
|
||||||
_cursor.delta.x += dx;
|
_cursor.delta.x = dx;
|
||||||
_cursor.delta.y += dy;
|
_cursor.delta.y = dy;
|
||||||
SDL_CALL SDL_WarpMouse(_cursor.pos.x, _cursor.pos.y);
|
SDL_CALL SDL_WarpMouse(_cursor.pos.x, _cursor.pos.y);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -426,8 +426,8 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
|
||||||
int dx = x - _cursor.pos.x;
|
int dx = x - _cursor.pos.x;
|
||||||
int dy = y - _cursor.pos.y;
|
int dy = y - _cursor.pos.y;
|
||||||
if (dx != 0 || dy != 0) {
|
if (dx != 0 || dy != 0) {
|
||||||
_cursor.delta.x += dx;
|
_cursor.delta.x = dx;
|
||||||
_cursor.delta.y += dy;
|
_cursor.delta.y = dy;
|
||||||
|
|
||||||
pt.x = _cursor.pos.x;
|
pt.x = _cursor.pos.x;
|
||||||
pt.y = _cursor.pos.y;
|
pt.y = _cursor.pos.y;
|
||||||
|
@ -436,8 +436,8 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
|
||||||
SetCursorPos(pt.x, pt.y);
|
SetCursorPos(pt.x, pt.y);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_cursor.delta.x += x - _cursor.pos.x;
|
_cursor.delta.x = x - _cursor.pos.x;
|
||||||
_cursor.delta.y += y - _cursor.pos.y;
|
_cursor.delta.y = y - _cursor.pos.y;
|
||||||
_cursor.pos.x = x;
|
_cursor.pos.x = x;
|
||||||
_cursor.pos.y = y;
|
_cursor.pos.y = y;
|
||||||
_cursor.dirty = true;
|
_cursor.dirty = true;
|
||||||
|
@ -872,7 +872,6 @@ void VideoDriver_Win32::MainLoop()
|
||||||
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
|
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
|
||||||
|
|
||||||
GameLoop();
|
GameLoop();
|
||||||
_cursor.delta.x = _cursor.delta.y = 0;
|
|
||||||
|
|
||||||
if (_force_full_redraw) MarkWholeScreenDirty();
|
if (_force_full_redraw) MarkWholeScreenDirty();
|
||||||
|
|
||||||
|
|
|
@ -1900,7 +1900,7 @@ static void HandleKeyScrolling()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MouseLoop(MouseClick click, int mousewheel)
|
static void MouseLoop(MouseClick click, int mousewheel)
|
||||||
{
|
{
|
||||||
DecreaseWindowCounters();
|
DecreaseWindowCounters();
|
||||||
HandlePlacePresize();
|
HandlePlacePresize();
|
||||||
|
@ -2043,6 +2043,11 @@ void HandleMouseEvents()
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseLoop(click, mousewheel);
|
MouseLoop(click, mousewheel);
|
||||||
|
|
||||||
|
/* We have moved the mouse the required distance,
|
||||||
|
* no need to move it at any later time. */
|
||||||
|
_cursor.delta.x = 0;
|
||||||
|
_cursor.delta.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue