Rigs of Rods 2026.01
Soft-body Physics Simulation
Loading...
Searching...
No Matches
ServerScriptFileSafe.cpp
Go to the documentation of this file.
1
2// =============================================================================
3// This file is adopted from rorserver at commit 4a7109ae2d9a081ccfdad8cc696dc54efe49acb3
4// Changes from the original are marked with "//RIGSOFRODS"
5// =============================================================================
6
7/*
8This file is part of "Rigs of Rods Server" (Relay mode)
9
10Copyright 2007 Pierre-Michel Ricordel
11Copyright 2014+ Rigs of Rods Community
12
13"Rigs of Rods Server" is free software: you can redistribute it
14and/or modify it under the terms of the GNU General Public License
15as published by the Free Software Foundation, either version 3
16of the License, or (at your option) any later version.
17
18"Rigs of Rods Server" is distributed in the hope that it will
19be useful, but WITHOUT ANY WARRANTY; without even the implied
20warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21See the GNU General Public License for more details.
22
23You should have received a copy of the GNU General Public License
24along with Foobar. If not, see <http://www.gnu.org/licenses/>.
25*/
26
28
29// RIGSOFRODS: from rorserver's 'ScriptFileSafe.cpp'
30
31#ifdef USE_ANGELSCRIPT
32
33using namespace RoR; // RIGSOFRODS
34using namespace AngelScript;
35
39
40void RoR::RegisterScriptFile_Native(asIScriptEngine *engine) {
41 int r;
42
43 r = engine->RegisterObjectType("file", 0, asOBJ_REF);
44 assert(r >= 0);
45 r = engine->RegisterObjectBehaviour("file", asBEHAVE_FACTORY, "file @f()", asFUNCTION(ScriptFile_Factory),
46 asCALL_CDECL);
47 assert(r >= 0);
48 r = engine->RegisterObjectBehaviour("file", asBEHAVE_ADDREF, "void f()", asMETHOD(ScriptFileSafe, AddRef),
49 asCALL_THISCALL);
50 assert(r >= 0);
51 r = engine->RegisterObjectBehaviour("file", asBEHAVE_RELEASE, "void f()", asMETHOD(ScriptFileSafe, Release),
52 asCALL_THISCALL);
53 assert(r >= 0);
54
55 r = engine->RegisterObjectMethod("file", "int open(const string &in, const string &in)",
56 asMETHOD(ScriptFileSafe, Open), asCALL_THISCALL);
57 assert(r >= 0);
58 r = engine->RegisterObjectMethod("file", "int close()", asMETHOD(ScriptFileSafe, Close), asCALL_THISCALL);
59 assert(r >= 0);
60 r = engine->RegisterObjectMethod("file", "int getSize() const", asMETHOD(ScriptFileSafe, GetSize), asCALL_THISCALL);
61 assert(r >= 0);
62 r = engine->RegisterObjectMethod("file", "bool isEndOfFile() const", asMETHOD(ScriptFileSafe, IsEOF),
63 asCALL_THISCALL);
64 assert(r >= 0);
65 r = engine->RegisterObjectMethod("file", "int readString(uint, string &out)", asMETHOD(ScriptFileSafe, ReadString),
66 asCALL_THISCALL);
67 assert(r >= 0);
68 r = engine->RegisterObjectMethod("file", "int readLine(string &out)", asMETHOD(ScriptFileSafe, ReadLine),
69 asCALL_THISCALL);
70 assert(r >= 0);
71 r = engine->RegisterObjectMethod("file", "int64 readInt(uint)", asMETHOD(ScriptFileSafe, ReadInt), asCALL_THISCALL);
72 assert(r >= 0);
73 r = engine->RegisterObjectMethod("file", "uint64 readUInt(uint)", asMETHOD(ScriptFileSafe, ReadUInt),
74 asCALL_THISCALL);
75 assert(r >= 0);
76 r = engine->RegisterObjectMethod("file", "float readFloat()", asMETHOD(ScriptFileSafe, ReadFloat), asCALL_THISCALL);
77 assert(r >= 0);
78 r = engine->RegisterObjectMethod("file", "double readDouble()", asMETHOD(ScriptFileSafe, ReadDouble),
79 asCALL_THISCALL);
80 assert(r >= 0);
81
82 r = engine->RegisterObjectMethod("file", "int writeString(const string &in)", asMETHOD(ScriptFileSafe, WriteString),
83 asCALL_THISCALL);
84 assert(r >= 0);
85 r = engine->RegisterObjectMethod("file", "int writeInt(int64, uint)", asMETHOD(ScriptFileSafe, WriteInt),
86 asCALL_THISCALL);
87 assert(r >= 0);
88 r = engine->RegisterObjectMethod("file", "int writeUInt(uint64, uint)", asMETHOD(ScriptFileSafe, WriteUInt),
89 asCALL_THISCALL);
90 assert(r >= 0);
91 r = engine->RegisterObjectMethod("file", "int writeFloat(float)", asMETHOD(ScriptFileSafe, WriteFloat),
92 asCALL_THISCALL);
93 assert(r >= 0);
94 r = engine->RegisterObjectMethod("file", "int writeDouble(double)", asMETHOD(ScriptFileSafe, WriteDouble),
95 asCALL_THISCALL);
96 assert(r >= 0);
97
98 r = engine->RegisterObjectMethod("file", "int getPos() const", asMETHOD(ScriptFileSafe, GetPos), asCALL_THISCALL);
99 assert(r >= 0);
100 r = engine->RegisterObjectMethod("file", "int setPos(int)", asMETHOD(ScriptFileSafe, SetPos), asCALL_THISCALL);
101 assert(r >= 0);
102 r = engine->RegisterObjectMethod("file", "int movePos(int)", asMETHOD(ScriptFileSafe, MovePos), asCALL_THISCALL);
103 assert(r >= 0);
104
105 assert(r >= 0);
106}
107
108
112
116
118 ++refCount;
119}
120
122 if (--refCount == 0)
123 delete this;
124}
125
126int ScriptFileSafe::Open(const std::string &filename, const std::string &mode) {
127 // Close the previously opened file handle
128 if (m_stream)
129 m_stream->close();
130
131 // Validate the mode
132 std::string m;
133#if AS_WRITE_OPS == 1
134 if (mode != "r" && mode != "w" && mode != "a")
135#else
136 if( mode != "r" )
137#endif
138 return -2;
139 else
140 m = mode;
141
142 // By default windows translates "\r\n" to "\n", but we want to read the file as-is.
143 m += "b";
144
145 std::string myFilename = filename;
146
147 // Remove the possible .asdata extension
148 if (myFilename.length() > 7 && myFilename.substr(myFilename.length() - 7, 7) == ".asdata")
149 myFilename = myFilename.substr(0, myFilename.length() - 7);
150
151 // Replace all forbidden characters in the filename
152 std::string allowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-";
153 for (std::string::iterator it = myFilename.begin(); it < myFilename.end(); ++it) {
154 if (allowedChars.find(*it) == std::string::npos)
155 *it = '_';
156 }
157
158 // Open the file
159 try
160 {
161 m_stream = Ogre::ResourceGroupManager::getSingleton().openResource(myFilename, RGN_SERVER_SCRIPTS);
162 }
163 catch (...)
164 {
165 HandleGenericException("file.open()");
166 return -3;
167 }
168
169 return 0;
170}
171
173 if (!m_stream)
174 return -1;
175
176 m_stream->close();
177 return 0;
178}
179
181 if (!m_stream)
182 return -1;
183
184 return m_stream->size();
185}
186
188 if (!m_stream)
189 return -1;
190
191 return m_stream->tell();
192}
193
195 if (!m_stream)
196 return -1;
197
198 m_stream->seek(pos);
199
200 return 0;
201}
202
204 if (!m_stream)
205 return -1;
206
207 m_stream->seek(m_stream->tell() + delta);
208
209 return 0;
210}
211
212int ScriptFileSafe::ReadString(unsigned int length, std::string &str) {
213 if (!m_stream)
214 return 0;
215
216 // Read the string
217 str.resize(length);
218 size_t size = (int)m_stream->read(&str[0], length);
219 str.resize(size);
220
221 return static_cast<int>(size);
222}
223
224int ScriptFileSafe::ReadLine(std::string &str) {
225 if (!m_stream)
226 return 0;
227
228 char buf[2000] = {};
229 size_t count = m_stream->readLine(buf, 2000);
230 str.assign(buf, count);
231
232 return static_cast<int>(count);
233}
234
235asINT64 ScriptFileSafe::ReadInt(asUINT bytes) {
236 if (!m_stream)
237 return 0;
238
239 if (bytes > 8) bytes = 8;
240 if (bytes == 0) return 0;
241
242 unsigned char buf[8];
243 size_t r = m_stream->read(buf, bytes);
244 if (r == 0) return 0;
245
246 asINT64 val = 0;
247
248 unsigned int n = 0;
249 for (; n < bytes; n++)
250 val |= asQWORD(buf[n]) << (n * 8);
251 if (buf[0] & 0x80)
252 for (; n < 8; n++)
253 val |= asQWORD(0xFF) << (n * 8);
254
255
256 return val;
257}
258
259asQWORD ScriptFileSafe::ReadUInt(asUINT bytes) {
260 if (!m_stream)
261 return 0;
262
263 if (bytes > 8) bytes = 8;
264 if (bytes == 0) return 0;
265
266 unsigned char buf[8];
267 size_t r = m_stream->read(buf, bytes);
268 if (r == 0) return 0;
269
270 asQWORD val = 0;
271
272 unsigned int n = 0;
273 for (; n < bytes; n++)
274 val |= asQWORD(buf[n]) << (n * 8);
275
276
277 return val;
278}
279
281 if (!m_stream)
282 return 0;
283
284 unsigned char buf[4];
285 size_t r = m_stream->read(buf, 4);
286 if (r == 0) return 0;
287
288 asUINT val = 0;
289
290 unsigned int n = 0;
291 for (; n < 4; n++)
292 val |= asUINT(buf[n]) << (n * 8);
293
294
295 return *reinterpret_cast<float *>(&val);
296}
297
299 if (!m_stream)
300 return 0;
301
302 unsigned char buf[8];
303 size_t r = m_stream->read(buf, 8);
304 if (r == 0) return 0;
305
306 asQWORD val = 0;
307
308 unsigned int n = 0;
309 for (; n < 8; n++)
310 val |= asQWORD(buf[n]) << (n * 8);
311
312
313 return *reinterpret_cast<double *>(&val);
314}
315
317 if (!m_stream)
318 return true;
319
320 return m_stream->eof();
321}
322
323int ScriptFileSafe::WriteString(const std::string &str) {
324 if (!m_stream)
325 return -1;
326
327 // Write the entire string
328 size_t r = m_stream->write(&str[0], str.length());
329 return int(r);
330}
331
332int ScriptFileSafe::WriteInt(asINT64 val, asUINT bytes) {
333 if (!m_stream)
334 return 0;
335
336 unsigned char buf[8];
337
338 for (unsigned int n = 0; n < bytes; n++)
339 buf[n] = (val >> (n * 8)) & 0xFF;
340
341
342 size_t r = m_stream->write(&buf, bytes);
343 return int(r);
344}
345
346int ScriptFileSafe::WriteUInt(asQWORD val, asUINT bytes) {
347 if (!m_stream)
348 return 0;
349
350 unsigned char buf[8];
351
352 for (unsigned int n = 0; n < bytes; n++)
353 buf[n] = (val >> (n * 8)) & 0xFF;
354
355
356 size_t r = m_stream->write(&buf, bytes);
357 return int(r);
358}
359
361 if (!m_stream)
362 return 0;
363
364 unsigned char buf[4];
365 asUINT val = *reinterpret_cast<asUINT *>(&f);
366
367 for (unsigned int n = 0; n < 4; n++)
368 buf[n] = (val >> (n * 8)) & 0xFF;
369
370
371 size_t r = m_stream->write(&buf, 4);
372 return int(r);
373}
374
376 if (!m_stream)
377 return 0;
378
379 unsigned char buf[8];
380 asQWORD val = *reinterpret_cast<asQWORD *>(&d);
381
382 for (unsigned int n = 0; n < 8; n++)
383 buf[n] = (val >> (n * 8)) & 0xFF;
384
385
386 size_t r = m_stream->write(&buf, 8);
387 return int(r);
388}
389
390#endif //USE_ANGELSCRIPT
#define RGN_SERVER_SCRIPTS
Definition Application.h:54
ScriptFileSafe * ScriptFile_Factory()
Ogre::DataStreamPtr m_stream
int WriteInt(AngelScript::asINT64 v, AngelScript::asUINT bytes)
AngelScript::asQWORD ReadUInt(AngelScript::asUINT bytes)
int WriteUInt(AngelScript::asQWORD v, AngelScript::asUINT bytes)
int Open(const std::string &filename, const std::string &mode)
int WriteString(const std::string &str)
int ReadLine(std::string &str)
AngelScript::asINT64 ReadInt(AngelScript::asUINT bytes)
int ReadString(unsigned int length, std::string &str)
void HandleGenericException(const std::string &from, BitMask_t flags)
void RegisterScriptFile_Native(AngelScript::asIScriptEngine *engine)