Commands.cpp 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. /******************************************************************************/
  4. // CS_VERSION_CHECK
  5. /******************************************************************************/
  6. void ClientSendVersion(Connection &conn)
  7. {
  8. File f; f.writeMem().putByte(CS_VERSION_CHECK).cmpUIntV(ClientServerVersion).putStr(ClientServerString).pos(0); conn.send(f);
  9. }
  10. bool ServerRecvVersion(File &f)
  11. {
  12. if(f.decUIntV()==ClientServerVersion)if(f.getStr()==ClientServerString)return true;
  13. return false;
  14. }
  15. void ServerSendVersion(Connection &conn, bool ok)
  16. {
  17. File f; f.writeMem().putByte(CS_VERSION_CHECK).putBool(ok).pos(0); conn.send(f, -1, false);
  18. }
  19. bool ClientRecvVersion(File &f)
  20. {
  21. return f.getBool();
  22. }
  23. /******************************************************************************/
  24. // CS_LOGIN
  25. /******************************************************************************/
  26. void ClientSendLogin(Connection &conn, C Str &email, C Str &pass, C Str &license_key, OS_VER os_ver)
  27. {
  28. File f; f.writeMem().putByte(CS_LOGIN)<<email<<license_key<<PassToMD5(pass); f.putByte(os_ver); f.pos(0); conn.send(f);
  29. }
  30. void ServerRecvLogin(File &f, Str &email, UID &pass, Str &license_key, OS_VER &os_ver)
  31. {
  32. f>>email>>license_key>>pass;
  33. os_ver=OS_VER(f.getByte());
  34. }
  35. void ServerSendLogin(Connection &conn, LOGIN_RESULT result, USER_ACCESS access)
  36. {
  37. File f; f.writeMem().putByte(CS_LOGIN).putByte(result).putByte(access); f.pos(0); conn.send(f, -1, false);
  38. }
  39. void ClientRecvLogin(File &f, LOGIN_RESULT &result, USER_ACCESS &access)
  40. {
  41. result=LOGIN_RESULT(f.getByte());
  42. access=USER_ACCESS (f.getByte());
  43. }
  44. /******************************************************************************/
  45. // CS_REGISTER
  46. /******************************************************************************/
  47. void ClientSendRegister(Connection &conn, C Str &email, C Str &pass, C Str &name)
  48. {
  49. File f; f.writeMem().putByte(CS_REGISTER)<<email<<name<<PassToMD5(pass); f.pos(0); conn.send(f);
  50. }
  51. void ServerRecvRegister(File &f, Str &email, UID &pass, Str &name)
  52. {
  53. f>>email>>name>>pass;
  54. }
  55. void ServerSendRegister(Connection &conn, REGISTER_RESULT result)
  56. {
  57. File f; f.writeMem().putByte(CS_REGISTER).putByte(result); f.pos(0); conn.send(f, -1, false);
  58. }
  59. void ClientRecvRegister(File &f, REGISTER_RESULT &result)
  60. {
  61. result=REGISTER_RESULT(f.getByte());
  62. }
  63. /******************************************************************************/
  64. // CS_FORGOT_PASS
  65. /******************************************************************************/
  66. void ClientSendForgotPass(Connection &conn, C Str &email)
  67. {
  68. File f; f.writeMem().putByte(CS_FORGOT_PASS)<<email; f.pos(0); conn.send(f);
  69. }
  70. void ServerRecvForgotPass(File &f, Str &email)
  71. {
  72. f>>email;
  73. }
  74. void ServerSendForgotPass(Connection &conn, FORGOT_PASS_RESULT result)
  75. {
  76. File f; f.writeMem().putByte(CS_FORGOT_PASS).putByte(result); f.pos(0); conn.send(f, -1, false);
  77. }
  78. void ClientRecvForgotPass(File &f, FORGOT_PASS_RESULT &result)
  79. {
  80. result=FORGOT_PASS_RESULT(f.getByte());
  81. }
  82. /******************************************************************************/
  83. // CS_CHANGE_PASS
  84. /******************************************************************************/
  85. void ClientSendChangePass(Connection &conn, C Str &email, C Str &new_pass, C Str &old_pass, uint change_pass_key)
  86. {
  87. File f; f.writeMem().putByte(CS_CHANGE_PASS)<<email<<PassToMD5(new_pass)<<PassToMD5(old_pass)<<change_pass_key; f.pos(0); conn.send(f);
  88. }
  89. void ServerRecvChangePass(File &f, Str &email, UID &new_pass, UID &old_pass, uint &change_pass_key)
  90. {
  91. f>>email>>new_pass>>old_pass>>change_pass_key;
  92. }
  93. void ServerSendChangePass(Connection &conn, CHANGE_PASS_RESULT result)
  94. {
  95. File f; f.writeMem().putByte(CS_CHANGE_PASS).putByte(result); f.pos(0); conn.send(f, -1, false);
  96. }
  97. void ClientRecvChangePass(File &f, CHANGE_PASS_RESULT &result)
  98. {
  99. result=CHANGE_PASS_RESULT(f.getByte());
  100. }
  101. /******************************************************************************/
  102. // CS_LICENSE_KEY
  103. /******************************************************************************/
  104. void ClientSendLicenseKey(Connection &conn, C Str &license_key)
  105. {
  106. File f; f.writeMem().putByte(CS_LICENSE_KEY)<<license_key; f.pos(0); conn.send(f);
  107. }
  108. void ServerRecvLicenseKey(File &f, Str &license_key)
  109. {
  110. f>>license_key;
  111. }
  112. /******************************************************************************/
  113. // CS_PROJECTS_LIST
  114. /******************************************************************************/
  115. void ClientSendProjectsListRequest(Connection &conn)
  116. {
  117. File f; f.writeMem().putByte(CS_PROJECTS_LIST); f.pos(0); conn.send(f, -1, false);
  118. }
  119. void ServerSendProjectsList(Connection &conn, Memx<Project> &projects)
  120. {
  121. File f; f.writeMem().putByte(CS_PROJECTS_LIST).cmpUIntV(projects.elms()); FREPAO(projects).save(f, true, Project::SAVE_ID_NAME); f.pos(0); conn.send(f, -1, false);
  122. }
  123. bool ClientRecvProjectsList(File &f, Memx<Project> &projects)
  124. {
  125. projects.setNum(f.decUIntV()); int ver; FREPA(projects)if(projects[i].load(f, ver, true, Project::SAVE_ID_NAME)!=LOAD_OK){projects.clear(); return false;}
  126. return true;
  127. }
  128. /******************************************************************************/
  129. // CS_PROJECT_OPEN
  130. /******************************************************************************/
  131. void ClientSendProjectOpen(Connection &conn, C UID &proj_id, C Str &proj_name)
  132. {
  133. File f; f.writeMem().putByte(CS_PROJECT_OPEN)<<proj_name<<proj_id; f.pos(0); conn.send(f, -1, false);
  134. }
  135. void ServerRecvProjectOpen(File &f, UID &proj_id, Str &proj_name)
  136. {
  137. f>>proj_name>>proj_id;
  138. }
  139. /******************************************************************************/
  140. // CS_PROJECT_DATA
  141. /******************************************************************************/
  142. void ClientSendGetProjectData(Connection &conn) // this asks the Server to send Data for currently opened project
  143. {
  144. File f; f.writeMem().putByte(CS_PROJECT_DATA); f.pos(0); conn.send(f, -1, false);
  145. }
  146. bool ServerSendProjectData(Connection &conn, Project &project)
  147. {
  148. File f; f.writeMem().putByte(CS_PROJECT_DATA);
  149. File data; project.save(data.writeMem(), true); data.pos(0);
  150. // for a big project of uncompressed "Data" file around 9MB, there were following compression results
  151. // COMPRESS_LZ4 9 -> 1.6MB 0.075s
  152. // COMPRESS_LZMA 5 -> 1.1MB 0.388s
  153. if(Compress(data, f, ServerNetworkCompression, ServerNetworkCompressionLevel)){f.pos(0); conn.send(f, -1, false); return true;}
  154. return false;
  155. }
  156. bool ClientRecvProjectData(File &f, Project &project)
  157. {
  158. File decompressed; if(Decompress(f, decompressed, true)){decompressed.pos(0); int ver; return project.load(decompressed, ver, true)==LOAD_OK;}
  159. return false;
  160. }
  161. /******************************************************************************/
  162. // CS_PROJECT_SETTINGS
  163. /******************************************************************************/
  164. void ClientSendProjectSettings(Connection &conn, Project &project)
  165. {
  166. File f; f.writeMem().putByte(CS_PROJECT_SETTINGS); project.save(f, true, Project::SAVE_SETTINGS); f.pos(0); conn.send(f, -1, false);
  167. }
  168. bool ServerRecvProjectSettings(File &f, Project &project)
  169. {
  170. int ver; return project.load(f, ver, true, Project::SAVE_SETTINGS)==LOAD_OK;
  171. }
  172. void ServerWriteProjectSettings(File &f, Project &project)
  173. {
  174. f.putByte(CS_PROJECT_SETTINGS); project.save(f, true, Project::SAVE_SETTINGS);
  175. }
  176. bool ClientRecvProjectSettings(File &f, Project &project)
  177. {
  178. int ver; return project.load(f, ver, true, Project::SAVE_SETTINGS)==LOAD_OK;
  179. }
  180. /******************************************************************************/
  181. // CS_NEW_ELM
  182. /******************************************************************************/
  183. void ClientSendNewElm(Connection &conn, Elm &elm)
  184. {
  185. File f; f.writeMem().putByte(CS_NEW_ELM); elm.compressNew(f); f.pos(0); conn.send(f, -1, false);
  186. }
  187. void ServerRecvNewElm(File &f, Elm &elm)
  188. {
  189. elm.decompressNew(f);
  190. }
  191. void ServerWriteNewElm(File &f, Elm &elm, C UID &proj_id)
  192. {
  193. f.putByte(CS_NEW_ELM); elm.compressNew(f); f<<proj_id;
  194. }
  195. void ClientRecvNewElm(File &f, Elm &elm, UID &proj_id)
  196. {
  197. elm.decompressNew(f); f>>proj_id;
  198. }
  199. /******************************************************************************/
  200. // CS_RENAME_ELM
  201. /******************************************************************************/
  202. void ClientSendRenameElm(Connection &conn, C UID &elm_id, C Str &name, C TimeStamp &name_time)
  203. {
  204. File f; f.writeMem().putByte(CS_RENAME_ELM)<<elm_id<<name_time<<name; f.pos(0); conn.send(f, -1, false);
  205. }
  206. void ServerRecvRenameElm(File &f, UID &elm_id, Str &name, TimeStamp &name_time)
  207. {
  208. f>>elm_id>>name_time>>name;
  209. }
  210. void ServerWriteRenameElm(File &f, C UID &elm_id, C Str &name, C TimeStamp &name_time, C UID &proj_id)
  211. {
  212. f.putByte(CS_RENAME_ELM)<<elm_id<<name_time<<proj_id<<name;
  213. }
  214. void ClientRecvRenameElm(File &f, UID &elm_id, Str &name, TimeStamp &name_time, UID &proj_id)
  215. {
  216. f>>elm_id>>name_time>>proj_id>>name;
  217. }
  218. /******************************************************************************/
  219. // CS_SET_ELM_PARENT
  220. /******************************************************************************/
  221. void ClientSendSetElmParent(Connection &conn, C UID &elm_id, C UID &parent_id, C TimeStamp &parent_time)
  222. {
  223. File f; f.writeMem().putByte(CS_SET_ELM_PARENT)<<elm_id<<parent_id<<parent_time; f.pos(0); conn.send(f, -1, false);
  224. }
  225. void ServerRecvSetElmParent(File &f, UID &elm_id, UID &parent_id, TimeStamp &parent_time)
  226. {
  227. f>>elm_id>>parent_id>>parent_time;
  228. }
  229. void ServerWriteSetElmParent(File &f, C UID &elm_id, C UID &parent_id, C TimeStamp &parent_time, C UID &proj_id)
  230. {
  231. f.putByte(CS_SET_ELM_PARENT)<<elm_id<<parent_id<<parent_time<<proj_id;
  232. }
  233. void ClientRecvSetElmParent(File &f, UID &elm_id, UID &parent_id, TimeStamp &parent_time, UID &proj_id)
  234. {
  235. f>>elm_id>>parent_id>>parent_time>>proj_id;
  236. }
  237. /******************************************************************************/
  238. // CS_REMOVE_ELMS
  239. /******************************************************************************/
  240. void ClientSendRemoveElms(Connection &conn, Memc<UID> &elm_ids, bool removed, C TimeStamp &removed_time)
  241. {
  242. if(elm_ids.elms()){File f; f.writeMem().putByte(CS_REMOVE_ELMS).cmpUIntV(elm_ids.elms())<<removed<<removed_time; FREPA(elm_ids)f<<elm_ids[i]; f.pos(0); conn.send(f, -1, false);}
  243. }
  244. void ServerRecvRemoveElms(File &f, Memc<UID> &elm_ids, bool &removed, TimeStamp &removed_time)
  245. {
  246. elm_ids.setNum(f.decUIntV()); f>>removed>>removed_time; FREPA(elm_ids)f>>elm_ids[i];
  247. }
  248. void ServerWriteRemoveElms(File &f, Memc<UID> &elm_ids, bool removed, C TimeStamp &removed_time, C UID &proj_id)
  249. {
  250. f.putByte(CS_REMOVE_ELMS).cmpUIntV(elm_ids.elms())<<removed<<removed_time<<proj_id; FREPA(elm_ids)f<<elm_ids[i];
  251. }
  252. void ClientRecvRemoveElms(File &f, Memc<UID> &elm_ids, bool &removed, TimeStamp &removed_time, UID &proj_id)
  253. {
  254. elm_ids.setNum(f.decUIntV()); f>>removed>>removed_time>>proj_id; FREPA(elm_ids)f>>elm_ids[i];
  255. }
  256. /******************************************************************************/
  257. // CS_NO_PUBLISH_ELMS
  258. /******************************************************************************/
  259. void ClientSendNoPublishElms(Connection &conn, Memc<UID> &elm_ids, bool no_publish, C TimeStamp &no_publish_time)
  260. {
  261. if(elm_ids.elms()){File f; f.writeMem().putByte(CS_NO_PUBLISH_ELMS).cmpUIntV(elm_ids.elms())<<no_publish<<no_publish_time; FREPA(elm_ids)f<<elm_ids[i]; f.pos(0); conn.send(f, -1, false);}
  262. }
  263. void ServerRecvNoPublishElms(File &f, Memc<UID> &elm_ids, bool &no_publish, TimeStamp &no_publish_time)
  264. {
  265. elm_ids.setNum(f.decUIntV()); f>>no_publish>>no_publish_time; FREPA(elm_ids)f>>elm_ids[i];
  266. }
  267. void ServerWriteNoPublishElms(File &f, Memc<UID> &elm_ids, bool no_publish, C TimeStamp &no_publish_time, C UID &proj_id)
  268. {
  269. f.putByte(CS_NO_PUBLISH_ELMS).cmpUIntV(elm_ids.elms())<<no_publish<<no_publish_time<<proj_id; FREPA(elm_ids)f<<elm_ids[i];
  270. }
  271. void ClientRecvNoPublishElms(File &f, Memc<UID> &elm_ids, bool &no_publish, TimeStamp &no_publish_time, UID &proj_id)
  272. {
  273. elm_ids.setNum(f.decUIntV()); f>>no_publish>>no_publish_time>>proj_id; FREPA(elm_ids)f>>elm_ids[i];
  274. }
  275. /******************************************************************************/
  276. // CS_GET_ELM_NAMES
  277. /******************************************************************************/
  278. void ClientSendGetElmNames(Connection &conn, Memc<UID> &elm_ids)
  279. {
  280. if(elm_ids.elms()){File f; f.writeMem().putByte(CS_GET_ELM_NAMES).cmpUIntV(elm_ids.elms()); FREPA(elm_ids)f<<elm_ids[i]; f.pos(0); conn.send(f, -1, false);}
  281. }
  282. void ServerRecvGetElmNames(File &f, Memc<UID> &elm_ids)
  283. {
  284. elm_ids.setNum(f.decUIntV()); FREPA(elm_ids)f>>elm_ids[i];
  285. }
  286. void ServerSendGetElmNames(Connection &conn, Memc<ElmName> &elm_names, C UID &proj_id)
  287. {
  288. if(elm_names.elms())
  289. {
  290. File f; f.writeMem().putByte(CS_GET_ELM_NAMES);
  291. File data; data.writeMem().cmpUIntV(elm_names.elms())<<proj_id; FREPA(elm_names)elm_names[i].save(data);
  292. data.pos(0); if(Compress(data, f, ServerNetworkCompression, ServerNetworkCompressionLevel)){f.pos(0); conn.send(f, -1, false);}
  293. }
  294. }
  295. void ClientRecvGetElmNames(File &f, Memc<ElmName> &elm_names, UID &proj_id)
  296. {
  297. File data; if(Decompress(f, data, true)){data.pos(0); elm_names.setNum(data.decUIntV()); data>>proj_id; FREPA(elm_names)elm_names[i].load(data);}
  298. }
  299. /******************************************************************************/
  300. // CS_GET_TEXTURES / CS_SET_TEXTURE
  301. /******************************************************************************/
  302. void ClientSendGetTextures(Connection &conn, Memc<UID> &tex_ids)
  303. {
  304. if(tex_ids.elms()){File f; f.writeMem().putByte(CS_GET_TEXTURES).cmpUIntV(tex_ids.elms()); FREPA(tex_ids)f<<tex_ids[i]; f.pos(0); conn.send(f, -1, false);}
  305. }
  306. void ServerRecvGetTextures(File &f, Memc<UID> &tex_ids)
  307. {
  308. tex_ids.setNum(f.decUIntV()); FREPA(tex_ids)f>>tex_ids[i];
  309. }
  310. bool ClientWriteSetTexture(File &f, C UID &tex_id, File &tex_data)
  311. {
  312. f.putByte(CS_SET_TEXTURE)<<tex_id; return Compress(tex_data, f, ClientNetworkCompression, ClientNetworkCompressionLevel);
  313. }
  314. void ServerRecvSetTexture(File &f, UID &tex_id, File &cmpr_tex_data)
  315. {
  316. f>>tex_id; f.copy(cmpr_tex_data);
  317. }
  318. void ServerWriteSetTexture(File &f, C UID &tex_id, File &cmpr_tex_data, C UID &proj_id)
  319. {
  320. f.putByte(CS_SET_TEXTURE); f<<tex_id<<proj_id; cmpr_tex_data.copy(f);
  321. }
  322. bool ClientRecvSetTexture(File &f, UID &tex_id, File &tex_data, UID &proj_id)
  323. {
  324. f>>tex_id>>proj_id; return Decompress(f, tex_data);
  325. }
  326. /******************************************************************************/
  327. // CS_GET_ELM_SHORT / CS_SET_ELM_SHORT
  328. /******************************************************************************/
  329. void ClientSendGetElmShort(Connection &conn, Memc<UID> &elm_ids)
  330. {
  331. if(elm_ids.elms()){File f; f.writeMem().putByte(CS_GET_ELM_SHORT).cmpUIntV(elm_ids.elms()); FREPA(elm_ids)f<<elm_ids[i]; f.pos(0); conn.send(f, -1, false);}
  332. }
  333. void ServerRecvGetElmShort(File &f, Memc<UID> &elm_ids)
  334. {
  335. elm_ids.setNum(f.decUIntV()); FREPA(elm_ids)f>>elm_ids[i];
  336. }
  337. void ClientSendSetElmShort(Connection &conn, Elm &elm, C Project &proj)
  338. {
  339. File f; f.writeMem().putByte(CS_SET_ELM_SHORT); elm.compressData(f);
  340. if(ElmFileInShort(elm.type))
  341. {
  342. File data; if(data.readTry(proj.basePath(elm)))data.copy(f);
  343. }
  344. f.pos(0); conn.send(f, -1, false);
  345. }
  346. bool ServerRecvSetElmShort(File &f, Elm &elm, File &data)
  347. {
  348. if(!elm.decompressData(f))return false; return f.copy(data);
  349. }
  350. void ServerWriteSetElmShort(File &f, Elm &elm, C Project &proj)
  351. {
  352. f.putByte(CS_SET_ELM_SHORT)<<proj.id; elm.compressData(f);
  353. if(ElmFileInShort(elm.type))
  354. {
  355. File data; if(data.readTry(proj.basePath(elm)))data.copy(f);
  356. }
  357. }
  358. bool ClientRecvSetElmShort(File &f, Elm &elm, File &data, UID &proj_id)
  359. {
  360. f>>proj_id; if(!elm.decompressData(f))return false; return f.copy(data);
  361. }
  362. /******************************************************************************/
  363. // CS_GET_ELM_LONG / CS_SET_ELM_LONG
  364. /******************************************************************************/
  365. void ClientSendGetElmLong(Connection &conn, Memc<UID> &elm_ids)
  366. {
  367. if(elm_ids.elms()){File f; f.writeMem().putByte(CS_GET_ELM_LONG).cmpUIntV(elm_ids.elms()); FREPA(elm_ids)f<<elm_ids[i]; f.pos(0); conn.send(f, -1, false);}
  368. }
  369. void ServerRecvGetElmLong(File &f, Memc<UID> &elm_ids)
  370. {
  371. elm_ids.setNum(f.decUIntV()); FREPA(elm_ids)f>>elm_ids[i];
  372. }
  373. void ClientWriteSetElmLong(File &elm_file, File &data_file, Elm &elm, Project &proj, bool &compress)
  374. {
  375. elm_file.writeMem().putByte(CS_SET_ELM_LONG); elm.compressData(elm_file);
  376. if(ElmHasFile(elm.type))
  377. {
  378. if(ElmSendBoth(elm.type))
  379. {
  380. File data; data.readTry(proj.editPath(elm)); elm_file.cmpUIntV(data.size()); data.copy(elm_file); // if sending both, then store edit in the 'elm_file', because we will keep 'elm_file' uncompressed, and only 'data_file' compressed for 'ElmCompressable'
  381. if(data.readTry(proj.gamePath(elm)))data.copy(data_file);
  382. }else
  383. {
  384. File data; if(data.readTry(proj.basePath(elm)))data.copy(data_file);
  385. }
  386. compress=ElmCompressable(elm.type); // actual compression will be done in secondary thread
  387. }
  388. }
  389. bool ServerRecvSetElmLong(File &f, Elm &elm, File &data, File &extra)
  390. {
  391. if(!elm.decompressData(f))return false;
  392. if(ElmHasFile(elm.type))
  393. {
  394. if(ElmSendBoth(elm.type))
  395. {
  396. f.copy(data, f.decUIntV());
  397. f.copy(extra);
  398. }else
  399. {
  400. f.copy(data);
  401. }
  402. }
  403. return true;
  404. }
  405. void ServerWriteSetElmLong(File &f, Elm &elm, C Project &proj)
  406. {
  407. f.putByte(CS_SET_ELM_LONG)<<proj.id; elm.compressData(f);
  408. if(ElmHasFile(elm.type))
  409. {
  410. if(ElmSendBoth(elm.type))
  411. {
  412. File data; data.readTry(proj.editPath(elm)); f.cmpUIntV(data.size()); data.copy(f);
  413. if(data.readTry(proj.gamePath(elm)))data.copy(f);
  414. }else
  415. {
  416. File data; if(data.readTry(proj.basePath(elm)))data.copy(f);
  417. }
  418. }
  419. }
  420. bool ClientRecvSetElmLong(File &f, Elm &elm, File &data, File &extra, UID &proj_id)
  421. {
  422. f>>proj_id; if(!elm.decompressData(f))return false;
  423. if(ElmHasFile(elm.type))
  424. {
  425. if(ElmSendBoth(elm.type))
  426. {
  427. f.copy(data, f.decUIntV());
  428. if(ElmCompressable(elm.type) ? !Decompress(f, extra) : !f.copy(extra))return false;
  429. }else
  430. {
  431. if(ElmCompressable(elm.type) ? !Decompress(f, data) : !f.copy(data))return false;
  432. }
  433. }
  434. return true;
  435. }
  436. /******************************************************************************/
  437. // CS_SET_ELM_FULL
  438. /******************************************************************************/
  439. void ClientWriteSetElmFull(File &elm_file, File &data_file, Elm &elm, Project &proj, bool &compress)
  440. {
  441. elm_file.writeMem().putByte(CS_SET_ELM_FULL); elm.save(elm_file, true, false);
  442. if(ElmHasFile(elm.type))
  443. {
  444. if(ElmSendBoth(elm.type))
  445. {
  446. File data; data.readTry(proj.editPath(elm)); elm_file.cmpUIntV(data.size()); data.copy(elm_file);
  447. if(data.readTry(proj.gamePath(elm)))data.copy(data_file);
  448. }else
  449. {
  450. File data; if(data.readTry(proj.basePath(elm)))data.copy(data_file);
  451. }
  452. compress=ElmCompressable(elm.type); // actual compression will be done in secondary thread
  453. }
  454. }
  455. bool ServerRecvSetElmFull(File &f, Elm &elm, File &data, File &extra)
  456. {
  457. if(!elm.load(f, true, false))return false;
  458. if(ElmHasFile(elm.type))
  459. {
  460. if(ElmSendBoth(elm.type))
  461. {
  462. f.copy(data, f.decUIntV());
  463. f.copy(extra);
  464. }else
  465. {
  466. f.copy(data);
  467. }
  468. }
  469. return true;
  470. }
  471. void ServerWriteSetElmFull(File &f, Elm &elm, C Project &proj)
  472. {
  473. f.putByte(CS_SET_ELM_FULL)<<proj.id; elm.save(f, true, false);
  474. if(ElmHasFile(elm.type))
  475. {
  476. if(ElmSendBoth(elm.type))
  477. {
  478. File data; data.readTry(proj.editPath(elm)); f.cmpUIntV(data.size()); data.copy(f);
  479. if(data.readTry(proj.gamePath(elm)))data.copy(f);
  480. }else
  481. {
  482. File data; if(data.readTry(proj.basePath(elm)))data.copy(f);
  483. }
  484. }
  485. }
  486. bool ClientRecvSetElmFull(File &f, Elm &elm, File &data, File &extra, UID &proj_id)
  487. {
  488. f>>proj_id; if(!elm.load(f, true, false))return false;
  489. if(ElmHasFile(elm.type))
  490. {
  491. if(ElmSendBoth(elm.type))
  492. {
  493. f.copy(data, f.decUIntV());
  494. if(ElmCompressable(elm.type) ? !Decompress(f, extra) : !f.copy(extra))return false;
  495. }else
  496. {
  497. if(ElmCompressable(elm.type) ? !Decompress(f, data) : !f.copy(data))return false;
  498. }
  499. }
  500. return true;
  501. }
  502. /******************************************************************************/
  503. // CS_GET_WORLD_VER
  504. /******************************************************************************/
  505. void ClientSendGetWorldVer(Connection &conn, C UID &world_id)
  506. {
  507. File f; f.writeMem().putByte(CS_GET_WORLD_VER)<<world_id; f.pos(0); conn.send(f, -1, false);
  508. }
  509. void ServerRecvGetWorldVer(File &f, UID &world_id)
  510. {
  511. f>>world_id;
  512. }
  513. void ServerSendGetWorldVer(Connection &conn, WorldVer *world_ver, C UID &world_id, C UID &proj_id)
  514. {
  515. File f; f.writeMem().putByte(CS_GET_WORLD_VER)<<world_id<<proj_id; f.putBool(world_ver!=null);
  516. if(world_ver)
  517. {
  518. File temp; world_ver->save(temp.writeMem(), true); temp.pos(0); Compress(temp, f, ServerNetworkCompression, ServerNetworkCompressionLevel);
  519. }
  520. f.pos(0); conn.send(f, -1, false);
  521. }
  522. void ClientRecvGetWorldVer(File &f, WorldVer &world_ver, UID &world_id, UID &proj_id)
  523. {
  524. f>>world_id>>proj_id;
  525. if(f.getBool())
  526. {
  527. File temp; if(Decompress(f, temp, true)){temp.pos(0); world_ver.load(temp, true);}
  528. }
  529. }
  530. /******************************************************************************/
  531. // CS_GET_WORLD_AREAS
  532. /******************************************************************************/
  533. void ClientSendGetWorldAreas(Connection &conn, C UID &world_id, Memc<AreaSync> &areas)
  534. {
  535. if(areas.elms())
  536. {
  537. File f; f.writeMem().putByte(CS_GET_WORLD_AREAS)<<world_id; f.cmpUIntV(areas.elms()); FREPA(areas)f<<areas[i].xy<<areas[i].flag; f.pos(0); conn.send(f, -1, false);
  538. }
  539. }
  540. void ServerRecvGetWorldAreas(File &f, UID &world_id, Memc<AreaSync> &areas)
  541. {
  542. f>>world_id; areas.setNum(f.decUIntV()); FREPA(areas)f>>areas[i].xy>>areas[i].flag;
  543. }
  544. /******************************************************************************/
  545. // CS_SET_WORLD_AREA
  546. /******************************************************************************/
  547. void WriteSetWorldArea(File &f, C UID &world_id, C VecI2 &area_xy, byte area_sync_flag, C AreaVer &ver, C Heightmap *hm, C Memc<ObjData> &objs, C Str &edit_path)
  548. {
  549. f<<world_id<<area_xy<<area_sync_flag;
  550. if(area_sync_flag&(AREA_SYNC_HEIGHT|AREA_SYNC_MTRL|AREA_SYNC_COLOR))
  551. {
  552. int res=(hm ? hm->resolution() : 0);
  553. f.cmpUIntV(res);
  554. if(area_sync_flag&AREA_SYNC_HEIGHT)
  555. {
  556. f<<ver.hm_height_time;
  557. REPD(y, res)
  558. REPD(x, res)f.putFlt(hm->height(x, y));
  559. }
  560. if(area_sync_flag&AREA_SYNC_MTRL)
  561. {
  562. f<<ver.hm_mtrl_time;
  563. f.cmpUIntV(hm ? hm->materials() : 0);
  564. if(hm)FREP(hm->materials())f<<hm->material(i).id();
  565. REPD(y, res)
  566. REPD(x, res){VecB4 m, i; hm->getMaterial(x, y, m, i); f<<m<<i;}
  567. }
  568. if(area_sync_flag&AREA_SYNC_COLOR)
  569. {
  570. f<<ver.hm_color_time;
  571. if(res)
  572. {
  573. f.putBool(hm->hasColor());
  574. if(hm->hasColor())
  575. {
  576. REPD(y, res)
  577. REPD(x, res){Color c=hm->color(x, y); f<<c.r<<c.g<<c.b;}
  578. }
  579. }
  580. }
  581. }
  582. if(area_sync_flag&AREA_SYNC_REMOVED)f<<ver.hm_removed_time;
  583. if(area_sync_flag&AREA_SYNC_OBJ )
  584. {
  585. f<<ver.obj_ver;
  586. objs.save(f, edit_path);
  587. }
  588. }
  589. bool RecvSetWorldArea(File &f, UID &world_id, VecI2 &area_xy, byte &area_sync_flag, AreaVer &ver, Heightmap &hm, Memc<ObjData> &objs, C Str &game_path, C Str &edit_path)
  590. {
  591. f>>world_id>>area_xy>>area_sync_flag;
  592. if(area_sync_flag&(AREA_SYNC_HEIGHT|AREA_SYNC_MTRL|AREA_SYNC_COLOR))
  593. {
  594. int res=f.decUIntV(); hm.create(res, 0, null, false, null, null, null, null, null, null, null, null);
  595. if(area_sync_flag&AREA_SYNC_HEIGHT)
  596. {
  597. f>>ver.hm_height_time;
  598. REPD(y, res)
  599. REPD(x, res)hm.height(x, y, f.getFlt());
  600. }
  601. if(area_sync_flag&AREA_SYNC_MTRL)
  602. {
  603. f>>ver.hm_mtrl_time;
  604. Mems<MaterialPtr> mtrls; mtrls.setNum(f.decUIntV());
  605. FREPA(mtrls){UID mtrl_id; f>>mtrl_id; if(mtrl_id.valid())mtrls[i]=game_path+EncodeFileName(mtrl_id);}
  606. REPD(y, res)
  607. REPD(x, res)
  608. {
  609. VecB4 m, i; f>>m>>i;
  610. hm.setMaterial(x, y, InRange(m.x, mtrls) ? mtrls[m.x] : MaterialPtr(), InRange(m.y, mtrls) ? mtrls[m.y] : MaterialPtr(), InRange(m.z, mtrls) ? mtrls[m.z] : MaterialPtr(), InRange(m.w, mtrls) ? mtrls[m.w] : MaterialPtr(), i);
  611. }
  612. }
  613. if(area_sync_flag&AREA_SYNC_COLOR)
  614. {
  615. f>>ver.hm_color_time;
  616. if(res)
  617. if(f.getBool())
  618. REPD(y, res)
  619. REPD(x, res){Color c; f>>c.r>>c.g>>c.b; c.a=255; hm.color(x, y, c);}
  620. }
  621. }
  622. if(area_sync_flag&AREA_SYNC_REMOVED)f>>ver.hm_removed_time;
  623. if(area_sync_flag&AREA_SYNC_OBJ )
  624. {
  625. f>>ver.obj_ver;
  626. if(!objs.load(f, edit_path))return false;
  627. }
  628. return true;
  629. }
  630. void ClientWriteSetWorldArea(File &elm, File &data, C UID &world_id, C VecI2 &area_xy, byte area_sync_flag, C AreaVer &ver, C Heightmap *hm)
  631. {
  632. elm.putByte(CS_SET_WORLD_AREA);
  633. WriteSetWorldArea(data, world_id, area_xy, area_sync_flag, ver, hm, Memc<ObjData>(), S);
  634. }
  635. bool ServerRecvSetWorldArea(File &f, UID &world_id, VecI2 &area_xy, byte &area_sync_flag, AreaVer &ver, Heightmap &hm, C Str &game_path, C Str &edit_path)
  636. {
  637. File data; if(Decompress(f, data, true))
  638. {
  639. Memc<ObjData> objs;
  640. data.pos(0); return RecvSetWorldArea(data, world_id, area_xy, area_sync_flag, ver, hm, objs, game_path, edit_path);
  641. }
  642. return false;
  643. }
  644. void ServerSendSetWorldArea(Connection &conn, C UID &world_id, C VecI2 &area_xy, byte area_sync_flag, C AreaVer &ver, C Heightmap *hm, Memc<ObjData> &objs, C UID &proj_id, C Str &edit_path)
  645. {
  646. File f; f.writeMem().putByte(CS_SET_WORLD_AREA);
  647. File data; data.writeMem()<<proj_id; WriteSetWorldArea(data, world_id, area_xy, area_sync_flag, ver, hm, objs, edit_path);
  648. data.pos(0); if(Compress(data, f, ServerNetworkCompression, ServerNetworkCompressionLevel)){f.pos(0); conn.send(f, -1, false);}
  649. }
  650. bool ClientRecvSetWorldArea(File &f, UID &world_id, VecI2 &area_xy, byte &area_sync_flag, AreaVer &ver, Heightmap &hm, Memc<ObjData> &objs, UID &proj_id, C Str &game_path, C Str &edit_path)
  651. {
  652. File data; if(Decompress(f, data, true))
  653. {
  654. data.pos(0); data>>proj_id; return RecvSetWorldArea(data, world_id, area_xy, area_sync_flag, ver, hm, objs, game_path, edit_path);
  655. }
  656. return false;
  657. }
  658. /******************************************************************************/
  659. // CS_SET_WORLD_OBJS
  660. /******************************************************************************/
  661. void ClientWriteSetWorldObjs(File &elm, File &data, C UID &world_id, C VecI2 &area_xy, Memc<ObjData> &objs, C Str &edit_path)
  662. {
  663. elm.putByte(CS_SET_WORLD_OBJS);
  664. data.cmpIntV(area_xy.x).cmpIntV(area_xy.y)<<world_id;
  665. objs.save(data, edit_path);
  666. }
  667. bool ServerRecvSetWorldObjs(File &f, UID &world_id, VecI2 &area_xy, Memc<ObjData> &objs, C Str &edit_path)
  668. {
  669. File data; if(Decompress(f, data, true))
  670. {
  671. data.pos(0); data.decIntV(area_xy.x).decIntV(area_xy.y)>>world_id;
  672. return objs.load(data, edit_path);
  673. }
  674. return false;
  675. }
  676. void ServerWriteSetWorldObjs(File &f, C UID &world_id, C VecI2 &area_xy, Memc<ObjData> &objs, C Str &edit_path, C UID &proj_id)
  677. {
  678. f.putByte(CS_SET_WORLD_OBJS).cmpIntV(area_xy.x).cmpIntV(area_xy.y)<<world_id<<proj_id;
  679. objs.save(f, edit_path);
  680. }
  681. bool ClientRecvSetWorldObjs(File &f, UID &world_id, VecI2 &area_xy, Memc<ObjData> &objs, C Str &edit_path, UID &proj_id)
  682. {
  683. f.decIntV(area_xy.x).decIntV(area_xy.y)>>world_id>>proj_id;
  684. return objs.load(f, edit_path);
  685. }
  686. /******************************************************************************/
  687. // CS_GET_WORLD_WAYPOINTS
  688. /******************************************************************************/
  689. void ClientSendGetWorldWaypoints(Connection &conn, C UID &world_id, Memc<UID> &waypoints)
  690. {
  691. if(waypoints.elms()){File f; f.writeMem().putByte(CS_GET_WORLD_WAYPOINTS)<<world_id; f.cmpUIntV(waypoints.elms()); FREPA(waypoints)f<<waypoints[i]; f.pos(0); conn.send(f, -1, false);}
  692. }
  693. void ServerRecvGetWorldWaypoints(File &f, UID &world_id, Memc<UID> &waypoints)
  694. {
  695. f>>world_id; waypoints.setNum(f.decUIntV()); FREPA(waypoints)f>>waypoints[i];
  696. }
  697. /******************************************************************************/
  698. // CS_SET_WORLD_WAYPOINT
  699. /******************************************************************************/
  700. void ClientSendSetWorldWaypoint(Connection &conn, C UID &world_id, C UID &waypoint_id, C Version &waypoint_ver, EditWaypoint &waypoint)
  701. {
  702. File f; f.writeMem().putByte(CS_SET_WORLD_WAYPOINT)<<world_id<<waypoint_id<<waypoint_ver; waypoint.save(f); f.pos(0); conn.send(f, -1, false);
  703. }
  704. bool ServerRecvSetWorldWaypoint(File &f, UID &world_id, UID &waypoint_id, Version &waypoint_ver, EditWaypoint &waypoint)
  705. {
  706. f>>world_id>>waypoint_id>>waypoint_ver; return waypoint.load(f);
  707. }
  708. void ServerWriteSetWorldWaypoint(File &f, C UID &world_id, C UID &waypoint_id, C Version &waypoint_ver, EditWaypoint &waypoint, C UID &proj_id)
  709. {
  710. f.putByte(CS_SET_WORLD_WAYPOINT)<<world_id<<waypoint_id<<waypoint_ver<<proj_id; waypoint.save(f);
  711. }
  712. bool ClientRecvSetWorldWaypoint(File &f, UID &world_id, UID &waypoint_id, Version &waypoint_ver, EditWaypoint &waypoint, UID &proj_id)
  713. {
  714. f>>world_id>>waypoint_id>>waypoint_ver>>proj_id; return waypoint.load(f);
  715. }
  716. /******************************************************************************/
  717. // CS_GET_WORLD_LAKES
  718. /******************************************************************************/
  719. void ClientSendGetWorldLakes(Connection &conn, C UID &world_id, Memc<UID> &lakes)
  720. {
  721. if(lakes.elms()){File f; f.writeMem().putByte(CS_GET_WORLD_LAKES)<<world_id; f.cmpUIntV(lakes.elms()); FREPA(lakes)f<<lakes[i]; f.pos(0); conn.send(f, -1, false);}
  722. }
  723. void ServerRecvGetWorldLakes(File &f, UID &world_id, Memc<UID> &lakes)
  724. {
  725. f>>world_id; lakes.setNum(f.decUIntV()); FREPA(lakes)f>>lakes[i];
  726. }
  727. /******************************************************************************/
  728. // CS_SET_WORLD_LAKE
  729. /******************************************************************************/
  730. void ClientSendSetWorldLake(Connection &conn, C UID &world_id, C UID &lake_id, C Version &lake_ver, Lake &lake)
  731. {
  732. File f; f.writeMem().putByte(CS_SET_WORLD_LAKE)<<world_id<<lake_id<<lake_ver; lake.save(f); f.pos(0); conn.send(f, -1, false);
  733. }
  734. bool ServerRecvSetWorldLake(File &f, UID &world_id, UID &lake_id, Version &lake_ver, Lake &lake)
  735. {
  736. f>>world_id>>lake_id>>lake_ver; return lake.load(f);
  737. }
  738. void ServerWriteSetWorldLake(File &f, C UID &world_id, C UID &lake_id, C Version &lake_ver, Lake &lake, C UID &proj_id)
  739. {
  740. f.putByte(CS_SET_WORLD_LAKE)<<world_id<<lake_id<<lake_ver<<proj_id; lake.save(f);
  741. }
  742. bool ClientRecvSetWorldLake(File &f, UID &world_id, UID &lake_id, Version &lake_ver, Lake &lake, UID &proj_id)
  743. {
  744. f>>world_id>>lake_id>>lake_ver>>proj_id; return lake.load(f);
  745. }
  746. /******************************************************************************/
  747. // CS_GET_WORLD_RIVERS
  748. /******************************************************************************/
  749. void ClientSendGetWorldRivers(Connection &conn, C UID &world_id, Memc<UID> &rivers)
  750. {
  751. if(rivers.elms()){File f; f.writeMem().putByte(CS_GET_WORLD_RIVERS)<<world_id; f.cmpUIntV(rivers.elms()); FREPA(rivers)f<<rivers[i]; f.pos(0); conn.send(f, -1, false);}
  752. }
  753. void ServerRecvGetWorldRivers(File &f, UID &world_id, Memc<UID> &rivers)
  754. {
  755. f>>world_id; rivers.setNum(f.decUIntV()); FREPA(rivers)f>>rivers[i];
  756. }
  757. /******************************************************************************/
  758. // CS_SET_WORLD_RIVER
  759. /******************************************************************************/
  760. void ClientSendSetWorldRiver(Connection &conn, C UID &world_id, C UID &river_id, C Version &river_ver, River &river)
  761. {
  762. File f; f.writeMem().putByte(CS_SET_WORLD_RIVER)<<world_id<<river_id<<river_ver; river.save(f); f.pos(0); conn.send(f, -1, false);
  763. }
  764. bool ServerRecvSetWorldRiver(File &f, UID &world_id, UID &river_id, Version &river_ver, River &river)
  765. {
  766. f>>world_id>>river_id>>river_ver; return river.load(f);
  767. }
  768. void ServerWriteSetWorldRiver(File &f, C UID &world_id, C UID &river_id, C Version &river_ver, River &river, C UID &proj_id)
  769. {
  770. f.putByte(CS_SET_WORLD_RIVER)<<world_id<<river_id<<river_ver<<proj_id; river.save(f);
  771. }
  772. bool ClientRecvSetWorldRiver(File &f, UID &world_id, UID &river_id, Version &river_ver, River &river, UID &proj_id)
  773. {
  774. f>>world_id>>river_id>>river_ver>>proj_id; return river.load(f);
  775. }
  776. /******************************************************************************/
  777. // CS_GET_MINI_MAP_VER
  778. /******************************************************************************/
  779. void ClientSendGetMiniMapVer(Connection &conn, C UID &mini_map_id)
  780. {
  781. File f; f.writeMem().putByte(CS_GET_MINI_MAP_VER)<<mini_map_id; f.pos(0); conn.send(f, -1, false);
  782. }
  783. void ServerRecvGetMiniMapVer(File &f, UID &mini_map_id)
  784. {
  785. f>>mini_map_id;
  786. }
  787. void ServerSendGetMiniMapVer(Connection &conn, MiniMapVer *mini_map_ver, C UID &mini_map_id, C UID &proj_id)
  788. {
  789. File f; f.writeMem().putByte(CS_GET_MINI_MAP_VER)<<mini_map_id<<proj_id; f.putBool(mini_map_ver!=null);
  790. if(mini_map_ver)
  791. {
  792. File temp; mini_map_ver->save(temp.writeMem(), true); temp.pos(0); Compress(temp, f, ServerNetworkCompression, ServerNetworkCompressionLevel);
  793. }
  794. f.pos(0); conn.send(f, -1, false);
  795. }
  796. void ClientRecvGetMiniMapVer(File &f, MiniMapVer &mini_map_ver, UID &mini_map_id, UID &proj_id)
  797. {
  798. f>>mini_map_id>>proj_id;
  799. if(f.getBool())
  800. {
  801. File temp; if(Decompress(f, temp, true)){temp.pos(0); mini_map_ver.load(temp, true);}
  802. }
  803. }
  804. /******************************************************************************/
  805. // CS_GET_MINI_MAP_IMAGES
  806. /******************************************************************************/
  807. void ClientSendGetMiniMapImages(Connection &conn, C UID &mini_map_id, Memc<VecI2> &images)
  808. {
  809. File f; f.writeMem().putByte(CS_GET_MINI_MAP_IMAGES)<<mini_map_id;
  810. f.cmpUIntV(images.elms()); FREPA(images)f.cmpIntV(images[i].x).cmpIntV(images[i].y); f.pos(0); conn.send(f, -1, false);
  811. }
  812. void ServerRecvGetMiniMapImages(File &f, UID &mini_map_id, Memc<VecI2> &images)
  813. {
  814. f>>mini_map_id; images.setNum(f.decUIntV()); FREPA(images)f.decIntV(images[i].x).decIntV(images[i].y);
  815. }
  816. /******************************************************************************/
  817. // CS_SET_MINI_MAP_SETTINGS
  818. /******************************************************************************/
  819. void ClientSendSetMiniMapSettings(Connection &conn, C UID &mini_map_id, C Game::MiniMap::Settings &settings, C TimeStamp &settings_time)
  820. {
  821. File f; f.writeMem().putByte(CS_SET_MINI_MAP_SETTINGS)<<mini_map_id<<settings_time; settings.save(f); f.pos(0); conn.send(f, -1, false);
  822. }
  823. bool ServerRecvSetMiniMapSettings(File &f, UID &mini_map_id, Game::MiniMap::Settings &settings, TimeStamp &settings_time)
  824. {
  825. f>>mini_map_id>>settings_time; return settings.load(f);
  826. }
  827. void ServerWriteSetMiniMapSettings(File &f, C UID &mini_map_id, C Game::MiniMap::Settings &settings, C TimeStamp &settings_time, C UID &proj_id)
  828. {
  829. f.putByte(CS_SET_MINI_MAP_SETTINGS)<<mini_map_id<<proj_id<<settings_time; settings.save(f);
  830. }
  831. bool ClientRecvSetMiniMapSettings(File &f, UID &mini_map_id, Game::MiniMap::Settings &settings, TimeStamp &settings_time, UID &proj_id)
  832. {
  833. f>>mini_map_id>>proj_id>>settings_time; return settings.load(f);
  834. }
  835. /******************************************************************************/
  836. // CS_SET_MINI_MAP_IMAGE
  837. /******************************************************************************/
  838. void ServerSendSetMiniMapImage(Connection &conn, C UID &mini_map_id, C VecI2 &image_xy, C TimeStamp &image_time, File &cmpr_image_data, C UID &proj_id)
  839. {
  840. File f; f.writeMem().putByte(CS_SET_MINI_MAP_IMAGE)<<mini_map_id<<proj_id<<image_xy<<image_time; cmpr_image_data.copy(f);
  841. f.pos(0); conn.send(f, -1, false);
  842. }
  843. bool ClientRecvSetMiniMapImage(File &f, UID &mini_map_id, VecI2 &image_xy, TimeStamp &image_time, File &image_data, UID &proj_id)
  844. {
  845. f>>mini_map_id>>proj_id>>image_xy>>image_time; Decompress(f, image_data); return true; // 'f' can be empty if it doesn't exist, so don't return error on decompress fail
  846. }
  847. void ClientWriteSetMiniMapImage(File &elm, File &data, C UID &mini_map_id, C VecI2 &image_xy, C TimeStamp &image_time, File &image_data)
  848. {
  849. elm.putByte(CS_SET_MINI_MAP_IMAGE)<<mini_map_id<<image_xy<<image_time; elm.putBool(image_data.is());
  850. image_data.copy(data); // 'data' will be compressed
  851. }
  852. bool ServerRecvSetMiniMapImage(File &f, UID &mini_map_id, VecI2 &image_xy, TimeStamp &image_time, bool &image_is, File &cmpr_image_data)
  853. {
  854. f>>mini_map_id>>image_xy>>image_time>>image_is; return f.copy(cmpr_image_data); // don't decompress image data on the server
  855. }
  856. /******************************************************************************/
  857. // CS_GET_CODE_VER
  858. /******************************************************************************/
  859. void ClientSendGetCodeVer(Connection &conn, Memc<ElmTypeVer> &elms)
  860. {
  861. elms.sort(ElmTypeVer::Compare); // sort on the client so server can access using binary search
  862. File f; f.writeMem().putByte(CS_GET_CODE_VER); elms.save(f); f.pos(0); conn.send(f, -1, false);
  863. }
  864. bool ServerRecvGetCodeVer(File &f, Memc<ElmTypeVer> &elms)
  865. {
  866. return elms.load(f);
  867. }
  868. /******************************************************************************/
  869. // CS_SET_CODE_DATA
  870. /******************************************************************************/
  871. void ServerSendSetCodeData(Connection &conn, C Memc<ElmCodeData> &elms, C UID &proj_id) // use compression because source code can be big
  872. {
  873. File data; data.writeMem()<<proj_id; elms.save(data); data.pos(0);
  874. File f; f.writeMem().putByte(CS_SET_CODE_DATA); Compress(data, f, ServerNetworkCompression, ServerNetworkCompressionLevel); f.pos(0); conn.send(f, -1, false);
  875. }
  876. bool ClientRecvSetCodeData(File &f, Memc<ElmCodeData> &elms, UID &proj_id)
  877. {
  878. File data; if(Decompress(f, data, true)){data.pos(0); data>>proj_id; return elms.load(data);}
  879. return false;
  880. }
  881. void ClientSendSetCodeData(Connection &conn, C Memc<ElmCodeData> &elms) // use compression because source code can be big
  882. {
  883. File data; data.writeMem(); elms.save(data); data.pos(0);
  884. File f; f.writeMem().putByte(CS_SET_CODE_DATA); Compress(data, f, ServerNetworkCompression, 9); f.pos(0); conn.send(f, -1, false);
  885. }
  886. bool ServerRecvSetCodeData(File &f, Memc<ElmCodeData> &elms)
  887. {
  888. File data; if(Decompress(f, data, true)){data.pos(0); return elms.load(data);}
  889. return false;
  890. }
  891. /******************************************************************************/
  892. // CS_CODE_SYNC_STATUS
  893. /******************************************************************************/
  894. void ServerSendCodeSyncStatus(Connection &conn, C Memc<ElmCodeBase> &elms, bool resync, C UID &proj_id) // use compression because source code can be big
  895. {
  896. File data; data.writeMem()<<resync<<proj_id; elms.save(data); data.pos(0);
  897. File f; f.writeMem().putByte(CS_CODE_SYNC_STATUS); Compress(data, f, ServerNetworkCompression, ServerNetworkCompressionLevel); f.pos(0); conn.send(f, -1, false);
  898. }
  899. bool ClientRecvCodeSyncStatus(File &f, Memc<ElmCodeBase> &elms, bool &resync, UID &proj_id)
  900. {
  901. File data; if(Decompress(f, data, true)){data.pos(0); data>>resync>>proj_id; return elms.load(data);}
  902. return false;
  903. }
  904. /******************************************************************************/
  905. /******************************************************************************/
  906. void ElmName::set(Elm &elm) {id=elm.id; time=elm.name_time; name=elm.name;}
  907. bool ElmName::save(File &f ) {f<<id<<time<<name; return f.ok();}
  908. bool ElmName::load(File &f ) {f>>id>>time>>name; return f.ok();}
  909. void AreaSync::set(uint flag, C VecI2 &xy) {T.flag=flag; T.xy=xy;}
  910. void ElmTypeVer::set(C UID &id, ELM_TYPE type, C Version &ver) {T.id=id; T.type=type; T.ver=ver;}
  911. void ElmTypeVer::set(C Elm &elm ) {set(elm.id, elm.type, elm.data ? elm.data->ver : Version());}
  912. bool ElmTypeVer::save(File &f)C {f<<id<<type<<ver; return f.ok();}
  913. bool ElmTypeVer::load(File &f) {f>>id>>type>>ver; return f.ok();}
  914. int ElmTypeVer::Compare(C ElmTypeVer &a, C ElmTypeVer &b ) {return ::Compare(a.id, b.id);}
  915. int ElmTypeVer::Compare(C ElmTypeVer &a, C UID &id) {return ::Compare(a.id, id);}
  916. void ElmCodeData::set(Elm &elm, Code *code)
  917. {
  918. ::ElmTypeVer::set(elm);
  919. switch(type)
  920. {
  921. case ELM_APP : if(ElmApp *elm_app=elm.appData())app=*elm_app; break;
  922. case ELM_CODE: if(code)T.code=*code; break;
  923. }
  924. }
  925. bool ElmCodeData::save(File &f)C
  926. {
  927. ::ElmTypeVer::save(f);
  928. if(type==ELM_CODE)code.save(f);
  929. if(type==ELM_APP )app .save(f);
  930. return f.ok();
  931. }
  932. bool ElmCodeData::load(File &f)
  933. {
  934. if(::ElmTypeVer::load(f))
  935. {
  936. if(type==ELM_CODE)if(!code.load(f))return false;
  937. if(type==ELM_APP )if(!app .load(f))return false;
  938. if(f.ok())return true;
  939. }
  940. return false;
  941. }
  942. void ElmCodeBase::set(C UID &id, C Str &data) {T.id=id; T.data=data;}
  943. bool ElmCodeBase::save(File &f)C {f<<id<<data; return f.ok();}
  944. bool ElmCodeBase::load(File &f) {f>>id>>data; return f.ok();}
  945. /******************************************************************************/