1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2 
3 #ifndef LUA_HANDLE_SYNCED
4 #define LUA_HANDLE_SYNCED
5 
6 #include <map>
7 #include <string>
8 using std::map;
9 using std::string;
10 
11 #include "LuaHandle.h"
12 #include "LuaRulesParams.h"
13 
14 struct lua_State;
15 class LuaSyncedCtrl;
16 class CLuaHandleSynced;
17 struct BuildInfo;
18 
19 
20 class CUnsyncedLuaHandle : public CLuaHandle
21 {
22 	friend class CLuaHandleSynced;
23 
24 	public: // call-ins
25 		bool DrawUnit(const CUnit* unit);
26 		bool DrawFeature(const CFeature* feature);
27 		bool DrawShield(const CUnit* unit, const CWeapon* weapon);
28 		bool DrawProjectile(const CProjectile* projectile);
29 
30 	public: // all non-eventhandler callins
31 		void RecvFromSynced(lua_State* srcState, int args); // not an engine call-in
32 
33 	protected:
34 		CUnsyncedLuaHandle(CLuaHandleSynced* base, const string& name, int order);
35 		virtual ~CUnsyncedLuaHandle();
36 
37 		bool Init(const string& code, const string& file);
38 
GetUnsyncedHandle(lua_State * L)39 		static CUnsyncedLuaHandle* GetUnsyncedHandle(lua_State* L) {
40 			assert(dynamic_cast<CUnsyncedLuaHandle*>(CLuaHandle::GetHandle(L)));
41 			return static_cast<CUnsyncedLuaHandle*>(CLuaHandle::GetHandle(L));
42 		}
43 
44 	protected:
45 		CLuaHandleSynced& base;
46 };
47 
48 
49 
50 class CSyncedLuaHandle : public CLuaHandle
51 {
52 	friend class CLuaHandleSynced;
53 
54 	public: // call-ins
55 		bool CommandFallback(const CUnit* unit, const Command& cmd);
56 		bool AllowCommand(const CUnit* unit, const Command& cmd, bool fromSynced);
57 
58 		bool AllowUnitCreation(const UnitDef* unitDef, const CUnit* builder, const BuildInfo* buildInfo);
59 		bool AllowUnitTransfer(const CUnit* unit, int newTeam, bool capture);
60 		bool AllowUnitBuildStep(const CUnit* builder, const CUnit* unit, float part);
61 		bool AllowFeatureCreation(const FeatureDef* featureDef, int allyTeamID, const float3& pos);
62 		bool AllowFeatureBuildStep(const CUnit* builder, const CFeature* feature, float part);
63 		bool AllowResourceLevel(int teamID, const string& type, float level);
64 		bool AllowResourceTransfer(int oldTeam, int newTeam, const string& type, float amount);
65 		bool AllowDirectUnitControl(int playerID, const CUnit* unit);
66 		bool AllowBuilderHoldFire(const CUnit* unit, int action);
67 		bool AllowStartPosition(int playerID, unsigned char readyState, const float3& clampedPos, const float3& rawPickPos);
68 
69 		bool TerraformComplete(const CUnit* unit, const CUnit* build);
70 		bool MoveCtrlNotify(const CUnit* unit, int data);
71 
72 		int AllowWeaponTargetCheck(unsigned int attackerID, unsigned int attackerWeaponNum, unsigned int attackerWeaponDefID);
73 		bool AllowWeaponTarget(
74 			unsigned int attackerID,
75 			unsigned int targetID,
76 			unsigned int attackerWeaponNum,
77 			unsigned int attackerWeaponDefID,
78 			float* targetPriority
79 		);
80 		bool AllowWeaponInterceptTarget(const CUnit* interceptorUnit, const CWeapon* interceptorWeapon, const CProjectile* interceptorTarget);
81 
82 		bool UnitPreDamaged(
83 			const CUnit* unit,
84 			const CUnit* attacker,
85 			float damage,
86 			int weaponDefID,
87 			int projectileID,
88 			bool paralyzer,
89 			float* newDamage,
90 			float* impulseMult);
91 
92 		bool FeaturePreDamaged(
93 			const CFeature* feature,
94 			const CUnit* attacker,
95 			float damage,
96 			int weaponDefID,
97 			int projectileID,
98 			float* newDamage,
99 			float* impulseMult);
100 
101 		bool ShieldPreDamaged(const CProjectile*, const CWeapon*, const CUnit*, bool);
102 
103 		bool SyncedActionFallback(const string& line, int playerID);
104 
105 	protected:
106 		CSyncedLuaHandle(CLuaHandleSynced* base, const string& name, int order);
107 		virtual ~CSyncedLuaHandle();
108 
109 		bool Init(const string& code, const string& file);
110 
GetSyncedHandle(lua_State * L)111 		static CSyncedLuaHandle* GetSyncedHandle(lua_State* L) {
112 			assert(dynamic_cast<CSyncedLuaHandle*>(CLuaHandle::GetHandle(L)));
113 			return static_cast<CSyncedLuaHandle*>(CLuaHandle::GetHandle(L));
114 		}
115 
116 	protected:
117 		CLuaHandleSynced& base;
118 
119 		map<string, string> textCommands; // name, help
120 
121 	private:
122 		int origNextRef;
123 
124 	private: // call-outs
125 		static int SyncedRandom(lua_State* L);
126 		static int SyncedRandomSeed(lua_State* L);
127 
128 		static int SyncedNext(lua_State* L);
129 		static int SyncedPairs(lua_State* L);
130 
131 		static int SendToUnsynced(lua_State* L);
132 
133 		static int AddSyncedActionFallback(lua_State* L);
134 		static int RemoveSyncedActionFallback(lua_State* L);
135 
136 		static int GetWatchUnitDef(lua_State* L);
137 		static int SetWatchUnitDef(lua_State* L);
138 		static int GetWatchFeatureDef(lua_State* L);
139 		static int SetWatchFeatureDef(lua_State* L);
140 		static int GetWatchWeaponDef(lua_State* L);
141 		static int SetWatchWeaponDef(lua_State* L);
142 };
143 
144 
145 class CLuaHandleSynced
146 {
147 	public: // Non-eventhandler call-ins
GotChatMsg(const string & msg,int playerID)148 		bool GotChatMsg(const string& msg, int playerID) {
149 			return syncedLuaHandle.GotChatMsg(msg, playerID) ||
150 				unsyncedLuaHandle.GotChatMsg(msg, playerID);
151 		}
152 
RecvLuaMsg(const string & msg,int playerID)153 		bool RecvLuaMsg(const string& msg, int playerID) {
154 			return syncedLuaHandle.RecvLuaMsg(msg, playerID);
155 		}
156 
157 	public:
CheckStack()158 		void CheckStack() {
159 			syncedLuaHandle.CheckStack();
160 			unsyncedLuaHandle.CheckStack();
161 		}
162 
GetUnsyncedHandle(lua_State * L)163 		static CUnsyncedLuaHandle* GetUnsyncedHandle(lua_State* L) {
164 			if (CLuaHandle::GetHandleSynced(L)) {
165 				auto slh = CSyncedLuaHandle::GetSyncedHandle(L);
166 				return &slh->base.unsyncedLuaHandle;
167 			} else {
168 				return CUnsyncedLuaHandle::GetUnsyncedHandle(L);
169 			}
170 		}
171 
GetSyncedHandle(lua_State * L)172 		static CSyncedLuaHandle* GetSyncedHandle(lua_State* L) {
173 			if (CLuaHandle::GetHandleSynced(L)) {
174 				return CSyncedLuaHandle::GetSyncedHandle(L);
175 			} else {
176 				auto ulh = CUnsyncedLuaHandle::GetUnsyncedHandle(L);
177 				return &ulh->base.syncedLuaHandle;
178 			}
179 		}
180 
181 	protected:
182 		CLuaHandleSynced(const string& name, int order);
183 		virtual ~CLuaHandleSynced();
184 
185 		string LoadFile(const string& filename, const string& modes) const;
186 		void Init(const string& syncedFile, const string& unsyncedFile, const string& modes);
187 
IsValid()188 		bool IsValid() const {
189 			return syncedLuaHandle.IsValid() && unsyncedLuaHandle.IsValid();
190 		}
KillLua()191 		void KillLua() {
192 			syncedLuaHandle.KillLua();
193 			unsyncedLuaHandle.KillLua();
194 		}
195 
196 	#define SET_PERMISSION(name, type) \
197 		void Set ## name(const type arg) { \
198 			syncedLuaHandle.Set ## name(arg); \
199 			unsyncedLuaHandle.Set ## name(arg); \
200 		}
201 
202 		SET_PERMISSION(FullCtrl, bool);
203 		SET_PERMISSION(FullRead, bool);
204 		SET_PERMISSION(CtrlTeam, int);
205 		SET_PERMISSION(ReadTeam, int);
206 		SET_PERMISSION(ReadAllyTeam, int);
207 		SET_PERMISSION(SelectTeam, int);
208 
209 	#undef SET_PERMISSION
210 
211 	protected:
212 		friend class CUnsyncedLuaHandle;
213 		friend class CSyncedLuaHandle;
214 
215 		// hooks to add code during initialization
216 		virtual bool AddSyncedCode(lua_State* L) = 0;
217 		virtual bool AddUnsyncedCode(lua_State* L) = 0;
218 
219 		// call-outs
220 		static int LoadStringData(lua_State* L);
221 		static int CallAsTeam(lua_State* L);
222 
223 	public:
224 		CSyncedLuaHandle syncedLuaHandle;
225 		CUnsyncedLuaHandle unsyncedLuaHandle;
226 
227 	public:
GetGameParams()228 		static const LuaRulesParams::Params&  GetGameParams() { return gameParams; }
GetGameParamsMap()229 		static const LuaRulesParams::HashMap& GetGameParamsMap() { return gameParamsMap; }
230 
231 	private:
232 		//FIXME: add to CREG?
233 		static LuaRulesParams::Params  gameParams;
234 		static LuaRulesParams::HashMap gameParamsMap;
235 		friend class LuaSyncedCtrl;
236 };
237 
238 
239 #endif /* LUA_HANDLE_SYNCED */
240