changeset 12092:511a7baf7c34 draft

(svn r16502) -Fix [FS#2935]: when an AI was suspended while in a function called (indirectly) via call/acall/pcall OpenTTD crashed. Fix this by disallowing AIs to be suspended while called via call/acall/pcall. IMPORTANT FOR AI WRITERS: AIs can no longer call any DoCommand functions (change anything, build vehicles, etc.) in a function called (indirectly) via call/acall/pcall. Where possible, please rewrite your code so it doesn't use call/acall/pcall
author yexo <yexo@openttd.org>
date Mon, 01 Jun 2009 22:00:47 +0000
parents f1a0762b5788
children 1288972d5615
files src/3rdparty/squirrel/include/squirrel.h src/3rdparty/squirrel/squirrel/sqapi.cpp src/ai/ai_instance.hpp src/ai/api/ai_object.cpp src/script/squirrel.cpp src/script/squirrel.hpp
diffstat 6 files changed, 24 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/3rdparty/squirrel/include/squirrel.h
+++ b/src/3rdparty/squirrel/include/squirrel.h
@@ -275,6 +275,7 @@
 }SQRegFunction;
 
 /*vm*/
+SQUIRREL_API bool sq_can_suspend(HSQUIRRELVM v);
 SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize);
 SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize);
 SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v);
--- a/src/3rdparty/squirrel/squirrel/sqapi.cpp
+++ b/src/3rdparty/squirrel/squirrel/sqapi.cpp
@@ -90,6 +90,11 @@
 	}
 }
 
+bool sq_can_suspend(HSQUIRRELVM v)
+{
+	return v->_can_suspend;
+}
+
 void sq_seterrorhandler(HSQUIRRELVM v)
 {
 	SQObject o = stack_get(v, -1);
--- a/src/ai/ai_instance.hpp
+++ b/src/ai/ai_instance.hpp
@@ -30,6 +30,7 @@
 
 class AIInstance {
 public:
+	friend class AIObject;
 	AIInstance(class AIInfo *info);
 	~AIInstance();
 
--- a/src/ai/api/ai_object.cpp
+++ b/src/ai/api/ai_object.cpp
@@ -2,6 +2,11 @@
 
 /** @file ai_object.cpp Implementation of AIObject. */
 
+#include "../../stdafx.h"
+#include <squirrel.h>
+#include "../../script/squirrel.hpp"
+#include "../../company_base.h"
+
 #include "ai_log.hpp"
 #include "table/strings.h"
 #include "../ai.hpp"
@@ -158,7 +163,8 @@
 
 bool AIObject::GetAllowDoCommand()
 {
-	return GetStorage()->allow_do_command;
+	Squirrel *squirrel = Company::Get(_current_company)->ai_instance->engine;
+	return GetStorage()->allow_do_command && squirrel->CanSuspend();
 }
 
 void *&AIObject::GetEventPointer()
--- a/src/script/squirrel.cpp
+++ b/src/script/squirrel.cpp
@@ -508,3 +508,8 @@
 {
 	this->crashed = false;
 }
+
+bool Squirrel::CanSuspend()
+{
+	return sq_can_suspend(this->vm);
+}
--- a/src/script/squirrel.hpp
+++ b/src/script/squirrel.hpp
@@ -213,6 +213,11 @@
 	 * Reset the crashed status.
 	 */
 	void ResetCrashed();
+
+	/**
+	 * Are we allowed to suspend the squirrel script at this moment?
+	 */
+	bool CanSuspend();
 };
 
 #endif /* SQUIRREL_HPP */