Cuberite
A lightweight, fast and extensible game server for Minecraft
ManualBindings_World.cpp
Go to the documentation of this file.
1 
2 // ManualBindings_World.cpp
3 
4 // Implements the manual Lua API bindings for the cWorld class
5 
6 #include "Globals.h"
7 #include "tolua++/include/tolua++.h"
8 #include "../World.h"
9 #include "../UUID.h"
10 #include "ManualBindings.h"
11 #include "LuaState.h"
12 #include "PluginLua.h"
13 #include "LuaChunkStay.h"
14 
15 
22 static bool CheckParamVectorOr3Numbers(cLuaState & L, const char * a_VectorName, int a_Index, int & a_NextIndex)
23 {
24  if (L.IsParamUserType(a_Index, a_VectorName))
25  {
26  a_NextIndex = a_Index + 1;
27  return L.CheckParamUserType(a_Index, a_VectorName);
28  }
29 
30  a_NextIndex = a_Index + 3;
31  return L.CheckParamNumber(a_Index, a_Index + 2);
32 }
33 
34 
35 
36 
37 
39 template <typename T>
40 static bool GetStackVectorOr3Numbers(cLuaState & L, int a_Index, Vector3<T> & a_Return)
41 {
42  Vector3<T> * UserType;
43  if (L.GetStackValue(a_Index, UserType))
44  {
45  a_Return = *UserType;
46  return true;
47  }
48  return L.GetStackValues(a_Index, a_Return.x, a_Return.y, a_Return.z);
49 }
50 
51 
52 
53 
54 
55 static int tolua_cWorld_BroadcastBlockAction(lua_State * tolua_S)
56 {
57  /* Function signature:
58  void BroadcastBlockAction(number a_BlockX, number a_BlockY, number a_BlockZ, number a_number1, number a_number2, number a_BlockType, cClientHandle a_Exclude)
59  --or--
60  void BroadcastBlockAction(Vector3<int> a_BlockPos, number a_Byte1, number a_Byte2, number a_BlockType, cClientHandle a_Exclude)
61  */
62 
63  cLuaState L(tolua_S);
64  int Byte1Index;
65  if (
66  !L.CheckParamSelf("cWorld") ||
67  !CheckParamVectorOr3Numbers(L, "Vector3<int>", 2, Byte1Index) ||
68  !L.CheckParamNumber(Byte1Index, Byte1Index + 2)
69  )
70  {
71  return 0;
72  }
73 
74  if (Byte1Index != 3) // Not the vector overload
75  {
76  L.LogStackTrace();
77  LOGWARN("BroadcastBlockAction with 3 position arguments is deprecated, use vector-parametered version instead.");
78  }
79 
80  // Read the params:
81  cWorld * Self;
82  Vector3i BlockPos;
83  Byte Byte1, Byte2;
84  BLOCKTYPE BlockType;
85  const cClientHandle * Exclude = nullptr;
86 
87  if (
88  !L.GetStackValues(1, Self) ||
89  !GetStackVectorOr3Numbers(L, 2, BlockPos) ||
90  !L.GetStackValues(Byte1Index, Byte1, Byte2, BlockType)
91  )
92  {
93  return 0;
94  }
95 
96  // Optional param
97  L.GetStackValue(Byte1Index + 3, Exclude);
98 
99  Self->BroadcastBlockAction(BlockPos, Byte1, Byte2, BlockType, Exclude);
100  return 0;
101 }
102 
103 
104 
105 
106 
107 static int tolua_cWorld_BroadcastSoundEffect(lua_State * tolua_S)
108 {
109  /* Function signature:
110  void BroadcastSoundEffect(string a_SoundName, number a_X, number a_Y, number a_Z, number a_Volume, number a_Pitch, [cClientHandle * a_Exclude])
111  --or--
112  void BroadcastSoundEffect(string a_SoundName, Vector3d, number a_Volume, number a_Pitch, [cClientHandle a_Exclude])
113  */
114  cLuaState L(tolua_S);
115  int VolumeIndex;
116  if (
117  !L.CheckParamSelf("cWorld") ||
118  !L.CheckParamString(2) ||
119  !CheckParamVectorOr3Numbers(L, "Vector3<double>", 3, VolumeIndex) ||
120  !L.CheckParamNumber(VolumeIndex, VolumeIndex + 1)
121  )
122  {
123  return 0;
124  }
125 
126  if (VolumeIndex != 4) // Not the vector overload
127  {
128  L.LogStackTrace();
129  LOGWARN("BroadcastSoundEffect with 3 position arguments is deprecated, use vector-parametered version instead.");
130  }
131 
132  // Read the params:
133  cWorld * Self;
134  AString SoundName;
135  Vector3d BlockPos;
136  float Volume, Pitch;
137  const cClientHandle * Exclude = nullptr;
138 
139  if (
140  !L.GetStackValues(1, Self, SoundName) ||
141  !GetStackVectorOr3Numbers(L, 3, BlockPos) ||
142  !L.GetStackValues(VolumeIndex, Volume, Pitch)
143  )
144  {
145  return 0;
146  }
147 
148  // Optional param
149  L.GetStackValue(VolumeIndex + 2, Exclude);
150 
151  Self->BroadcastSoundEffect(SoundName, BlockPos, Volume, Pitch, Exclude);
152  return 0;
153 }
154 
155 
156 
157 
158 
159 static int tolua_cWorld_BroadcastSoundParticleEffect(lua_State * tolua_S)
160 {
161  /* Function signature:
162  World:BroadcastSoundParticleEffect(EffectID a_EffectID, Vector3i a_SrcPos, number a_Data, [cClientHandle a_Exclude])
163  --or--
164  void BroadcastSoundParticleEffect(EffectID a_EffectID, number a_SrcX, number a_SrcY, number a_SrcZ, number a_Data, [cClientHandle a_Exclude])
165  */
166  cLuaState L(tolua_S);
167  int DataIndex;
168  if (
169  !L.CheckParamSelf("cWorld") ||
170  !L.CheckParamNumber(2) ||
171  !CheckParamVectorOr3Numbers(L, "Vector3<int>", 3, DataIndex) ||
172  !L.CheckParamNumber(DataIndex)
173  )
174  {
175  return 0;
176  }
177 
178  if (DataIndex != 4) // Not the vector overload
179  {
180  L.LogStackTrace();
181  LOGWARN("BroadcastSoundParticleEffect with 3 position arguments is deprecated, use vector-parametered version instead.");
182  }
183 
184  // Read the params:
185  cWorld * World = nullptr;
186  Int32 EffectId;
187  Vector3i SrcPos;
188  int Data;
189  cClientHandle * ExcludeClient = nullptr;
190 
191  if (
192  !L.GetStackValues(1, World, EffectId) ||
193  !GetStackVectorOr3Numbers(L, 3, SrcPos) ||
194  !L.GetStackValue(DataIndex, Data)
195  )
196  {
197  return 0;
198  }
199 
200  // Optional param
201  L.GetStackValue(DataIndex + 1, ExcludeClient);
202 
203  World->BroadcastSoundParticleEffect(static_cast<EffectID>(EffectId), SrcPos, Data, ExcludeClient);
204  return 0;
205 }
206 
207 
208 
209 
210 
211 static int tolua_cWorld_BroadcastParticleEffect(lua_State * tolua_S)
212 {
213  /* Function signature:
214  World:BroadcastParticleEffect("Name", PosX, PosY, PosZ, OffX, OffY, OffZ, ParticleData, ParticleAmount, [ExcludeClient], [OptionalParam1], [OptionalParam2])
215  --or--
216  World:BroadcastParticleEffect("Name", SrcPos, Offset, ParticleData, ParticleAmount, [ExcludeClient], [OptionalParam1], [OptionalParam2])
217  */
218  cLuaState L(tolua_S);
219  int OffsetIndex, ParticleDataIndex;
220  if (
221  !L.CheckParamSelf("cWorld") ||
222  !L.CheckParamString(2) ||
223  !CheckParamVectorOr3Numbers(L, "Vector3<float>", 3, OffsetIndex) ||
224  !CheckParamVectorOr3Numbers(L, "Vector3<float>", OffsetIndex, ParticleDataIndex)
225  )
226  {
227  return 0;
228  }
229 
230  if ((OffsetIndex != 4) || (ParticleDataIndex != 5)) // Not the vector overload
231  {
232  L.LogStackTrace();
233  LOGWARN("BroadcastParticleEffect with 3 position and 3 offset arguments is deprecated, use vector-parametered version instead.");
234  }
235 
236  // Read the params:
237  cWorld * World = nullptr;
238  AString Name;
239  Vector3f SrcPos, Offset;
240  float ParticleData;
241  int ParticleAmount;
242  cClientHandle * ExcludeClient = nullptr;
243 
244  if (
245  !L.GetStackValues(1, World, Name) ||
246  !GetStackVectorOr3Numbers(L, 3, SrcPos) ||
247  !GetStackVectorOr3Numbers(L, OffsetIndex, Offset) ||
248  !L.GetStackValues(ParticleDataIndex, ParticleData, ParticleAmount)
249  )
250  {
251  return 0;
252  }
253 
254  // Read up to 3 more optional params:
255  L.GetStackValue(ParticleDataIndex + 2, ExcludeClient);
256 
257  std::array<int, 2> Data;
258  bool HasData = L.GetStackValues(ParticleDataIndex + 3, Data[0], Data[1]);
259 
260  if (HasData)
261  {
262  World->BroadcastParticleEffect(Name, SrcPos, Offset, ParticleData, ParticleAmount, Data, ExcludeClient);
263  }
264  else
265  {
266  World->BroadcastParticleEffect(Name, SrcPos, Offset, ParticleData, ParticleAmount, ExcludeClient);
267  }
268  return 0;
269 }
270 
271 
272 
273 
274 
275 static int tolua_cWorld_ChunkStay(lua_State * tolua_S)
276 {
277  /* Function signature:
278  World:ChunkStay(ChunkCoordTable, OnChunkAvailable, OnAllChunksAvailable)
279  ChunkCoordTable == { {Chunk1x, Chunk1z}, {Chunk2x, Chunk2z}, ... }
280  */
281 
282  cLuaState L(tolua_S);
283  if (
284  !L.CheckParamUserType (1, "cWorld") ||
285  !L.CheckParamTable (2) ||
286  !L.CheckParamFunctionOrNil(3, 4)
287  )
288  {
289  return 0;
290  }
291 
292  // Read the params:
293  cWorld * world;
294  cLuaState::cStackTablePtr chunkCoords;
295  cLuaState::cOptionalCallbackPtr onChunkAvailable, onAllChunksAvailable; // Callbacks may be unassigned at all - as a request to load / generate chunks
296  if (!L.GetStackValues(1, world, chunkCoords, onChunkAvailable, onAllChunksAvailable))
297  {
298  LOGWARNING("cWorld:ChunkStay(): Cannot read parameters, bailing out.");
299  L.LogStackTrace();
300  L.LogStackValues("Values on the stack");
301  return 0;
302  }
303  if (world == nullptr)
304  {
305  LOGWARNING("World:ChunkStay(): invalid world parameter");
306  L.LogStackTrace();
307  return 0;
308  }
309  ASSERT(chunkCoords != nullptr); // If the table was invalid, GetStackValues() would have failed
310 
311  // Read the chunk coords:
312  auto chunkStay = cpp14::make_unique<cLuaChunkStay>();
313  if (!chunkStay->AddChunks(*chunkCoords))
314  {
315  return 0;
316  }
317 
318  // Activate the ChunkStay:
319  chunkStay.release()->Enable(*world->GetChunkMap(), std::move(onChunkAvailable), std::move(onAllChunksAvailable));
320  return 0;
321 }
322 
323 
324 
325 
326 
327 static int tolua_cWorld_DoExplosionAt(lua_State * tolua_S)
328 {
329  /* Function signature:
330  World:DoExplosionAt(ExplosionSize, BlockX, BlockY, BlockZ, CanCauseFire, SourceType, [SourceData])
331  */
332 
333  cLuaState L(tolua_S);
334  if (
335  !L.CheckParamUserType (1, "cWorld") ||
336  !L.CheckParamNumber (2, 5) ||
337  !L.CheckParamBool (6) ||
338  !L.CheckParamNumber (7) ||
339  !L.CheckParamEnd (9)
340  )
341  {
342  return 0;
343  }
344 
345  // Read the params:
346  cWorld * World;
347  double ExplosionSize;
348  int BlockX, BlockY, BlockZ;
349  bool CanCauseFire;
350  int SourceTypeInt;
351  if (!L.GetStackValues(1, World, ExplosionSize, BlockX, BlockY, BlockZ, CanCauseFire, SourceTypeInt))
352  {
353  LOGWARNING("World:DoExplosionAt(): invalid parameters");
354  L.LogStackTrace();
355  return 0;
356  }
357  if ((SourceTypeInt < 0) || (SourceTypeInt >= esMax))
358  {
359  LOGWARNING("World:DoExplosionAt(): Invalid source type");
360  L.LogStackTrace();
361  return 0;
362  }
363  eExplosionSource SourceType;
364  void * SourceData;
365  switch (SourceTypeInt)
366  {
367  case esBed:
368  {
369  // esBed receives a Vector3i SourceData param:
370  Vector3i * pos = nullptr;
371  L.GetStackValue(8, pos);
372  SourceType = esBed;
373  SourceData = pos;
374  break;
375  }
376 
377  case esEnderCrystal:
378  case esGhastFireball:
379  case esMonster:
380  case esPrimedTNT:
381  case esWitherBirth:
382  case esWitherSkull:
383  {
384  // These all receive a cEntity descendant SourceData param:
385  cEntity * ent = nullptr;
386  L.GetStackValue(8, ent);
387  SourceType = static_cast<eExplosionSource>(SourceTypeInt);
388  SourceData = ent;
389  break;
390  }
391 
392  case esOther:
393  case esPlugin:
394  {
395  // esOther and esPlugin ignore their SourceData params
396  SourceType = static_cast<eExplosionSource>(SourceTypeInt);
397  SourceData = nullptr;
398  break;
399  }
400 
401  default:
402  {
403  LOGWARNING("cWorld:DoExplosionAt(): invalid SourceType parameter: %d", SourceTypeInt);
404  L.LogStackTrace();
405  return 0;
406  }
407  }
408 
409  // Create the actual explosion:
410  World->DoExplosionAt(ExplosionSize, BlockX, BlockY, BlockZ, CanCauseFire, SourceType, SourceData);
411 
412  return 0;
413 }
414 
415 
416 
417 
418 
419 static int tolua_cWorld_DoWithPlayerByUUID(lua_State * tolua_S)
420 {
421  // Check params:
422  cLuaState L(tolua_S);
423  if (
424  !L.CheckParamSelf("cWorld") ||
425  !L.CheckParamUUID(2) ||
426  !L.CheckParamFunction(3) ||
427  !L.CheckParamEnd(4)
428  )
429  {
430  return 0;
431  }
432 
433  // Get parameters:
434  cWorld * Self;
435  cUUID PlayerUUID;
436  cLuaState::cRef FnRef;
437  L.GetStackValues(1, Self, PlayerUUID, FnRef);
438 
439  if (PlayerUUID.IsNil())
440  {
441  return L.ApiParamError("Expected a non-nil UUID for parameter #1");
442  }
443  if (!FnRef.IsValid())
444  {
445  return L.ApiParamError("Expected a valid callback function for parameter #2");
446  }
447 
448  // Call the function:
449  bool res = Self->DoWithPlayerByUUID(PlayerUUID, [&](cPlayer & a_Player)
450  {
451  bool ret = false;
452  L.Call(FnRef, &a_Player, cLuaState::Return, ret);
453  return ret;
454  }
455  );
456 
457  // Push the result as the return value:
458  L.Push(res);
459  return 1;
460 }
461 
462 
463 
464 
465 
466 static int tolua_cWorld_DoWithNearestPlayer(lua_State * tolua_S)
467 {
468  // Check params:
469  cLuaState L(tolua_S);
470  if (
471  !L.CheckParamSelf("cWorld") ||
472  !L.CheckParamUserType(2, "Vector3<double>") ||
473  !L.CheckParamNumber(3) ||
474  !L.CheckParamFunction(4) ||
475  // Params 5 and 6 are optional bools, no check for those
476  !L.CheckParamEnd(7)
477  )
478  {
479  return 0;
480  }
481 
482  // Get parameters:
483  cWorld * Self;
484  Vector3d * Position;
485  double RangeLimit;
486  cLuaState::cRef FnRef;
487  bool CheckLineOfSight = true, IgnoreSpectators = true; // Defaults for the optional params
488  L.GetStackValues(1, Self, Position, RangeLimit, FnRef, CheckLineOfSight, IgnoreSpectators);
489 
490  if (Position == nullptr)
491  {
492  return L.ApiParamError("Expected a non-nil Vector3d for parameter #2");
493  }
494 
495  if (!FnRef.IsValid())
496  {
497  return L.ApiParamError("Expected a valid callback function for parameter #3");
498  }
499 
500  // Call the function:
501  bool res = Self->DoWithNearestPlayer(*Position, RangeLimit, [&](cPlayer & a_Player)
502  {
503  bool ret = false;
504  L.Call(FnRef, &a_Player, cLuaState::Return, ret);
505  return ret;
506  }, CheckLineOfSight, IgnoreSpectators);
507 
508  // Push the result as the return value:
509  L.Push(res);
510  return 1;
511 }
512 
513 
514 
515 
516 
517 static int tolua_cWorld_ForEachLoadedChunk(lua_State * tolua_S)
518 {
519  // Exported manually, because tolua doesn't support converting functions to functor types.
520  // Function signature: ForEachLoadedChunk(callback) -> bool
521 
522  cLuaState L(tolua_S);
523  if (
524  !L.CheckParamUserType(1, "cWorld") ||
525  !L.CheckParamFunction(2)
526  )
527  {
528  return 0;
529  }
530 
531  cPluginLua * Plugin = cManualBindings::GetLuaPlugin(tolua_S);
532  if (Plugin == nullptr)
533  {
534  return 0;
535  }
536 
537  // Read the params:
538  cWorld * World = static_cast<cWorld *>(tolua_tousertype(tolua_S, 1, nullptr));
539  if (World == nullptr)
540  {
541  LOGWARNING("World:ForEachLoadedChunk(): invalid world parameter");
542  L.LogStackTrace();
543  return 0;
544  }
545  cLuaState::cRef FnRef;
546  L.GetStackValues(2, FnRef);
547  if (!FnRef.IsValid())
548  {
549  return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #2");
550  }
551 
552  // Call the enumeration:
553  bool ret = World->ForEachLoadedChunk(
554  [&L, &FnRef](int a_ChunkX, int a_ChunkZ) -> bool
555  {
556  bool res = false; // By default continue the enumeration
557  L.Call(FnRef, a_ChunkX, a_ChunkZ, cLuaState::Return, res);
558  return res;
559  }
560  );
561 
562  // Push the return value:
563  L.Push(ret);
564  return 1;
565 }
566 
567 
568 
569 
570 
571 static int tolua_cWorld_GetBlockInfo(lua_State * tolua_S)
572 {
573  // Exported manually, because tolua would generate useless additional parameters (a_BlockType .. a_BlockSkyLight)
574  // Function signature: GetBlockInfo(BlockX, BlockY, BlockZ) -> BlockValid, [BlockType, BlockMeta, BlockSkyLight, BlockBlockLight]
575 
576  // Check params:
577  cLuaState L(tolua_S);
578  if (
579  !L.CheckParamUserType(1, "cWorld") ||
580  !L.CheckParamNumber(2, 4) ||
581  !L.CheckParamEnd(5)
582  )
583  {
584  return 0;
585  }
586 
587  // Get params:
588  cWorld * Self = nullptr;
589  int BlockX = 0;
590  int BlockY = 0;
591  int BlockZ = 0;
592  L.GetStackValues(1, Self, BlockX, BlockY, BlockZ);
593  if (Self == nullptr)
594  {
595  return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
596  }
597 
598  // Call the function:
599  BLOCKTYPE BlockType;
600  NIBBLETYPE BlockMeta, BlockSkyLight, BlockBlockLight;
601  bool res = Self->GetBlockInfo(BlockX, BlockY, BlockZ, BlockType, BlockMeta, BlockSkyLight, BlockBlockLight);
602 
603  // Push the returned values:
604  L.Push(res);
605  if (res)
606  {
607  L.Push(BlockType, BlockMeta, BlockSkyLight, BlockBlockLight);
608  return 5;
609  }
610  return 1;
611 }
612 
613 
614 
615 
616 
617 static int tolua_cWorld_GetBlockTypeMeta(lua_State * tolua_S)
618 {
619  // Exported manually, because tolua would generate useless additional parameters (a_BlockType, a_BlockMeta)
620  // Function signature: GetBlockTypeMeta(BlockX, BlockY, BlockZ) -> BlockValid, [BlockType, BlockMeta]
621 
622  // Check params:
623  cLuaState L(tolua_S);
624  if (
625  !L.CheckParamUserType(1, "cWorld") ||
626  !L.CheckParamNumber(2, 4) ||
627  !L.CheckParamEnd(5)
628  )
629  {
630  return 0;
631  }
632 
633  // Get params:
634  cWorld * Self = nullptr;
635  int BlockX = 0;
636  int BlockY = 0;
637  int BlockZ = 0;
638  L.GetStackValues(1, Self, BlockX, BlockY, BlockZ);
639  if (Self == nullptr)
640  {
641  return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
642  }
643 
644  // Call the function:
645  BLOCKTYPE BlockType;
646  NIBBLETYPE BlockMeta;
647  bool res = Self->GetBlockTypeMeta(BlockX, BlockY, BlockZ, BlockType, BlockMeta);
648 
649  // Push the returned values:
650  L.Push(res);
651  if (res)
652  {
653  L.Push(BlockType, BlockMeta);
654  return 3;
655  }
656  return 1;
657 }
658 
659 
660 
661 
662 
663 static int tolua_cWorld_GetSignLines(lua_State * tolua_S)
664 {
665  // Exported manually, because tolua would generate useless additional parameters (a_Line1 .. a_Line4)
666 
667  // Check params:
668  cLuaState L(tolua_S);
669  if (
670  !L.CheckParamUserType(1, "cWorld") ||
671  !L.CheckParamNumber(2, 4) ||
672  !L.CheckParamEnd(5)
673  )
674  {
675  return 0;
676  }
677 
678  // Get params:
679  cWorld * Self = nullptr;
680  int BlockX = 0;
681  int BlockY = 0;
682  int BlockZ = 0;
683  L.GetStackValues(1, Self, BlockX, BlockY, BlockZ);
684  if (Self == nullptr)
685  {
686  return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
687  }
688 
689  // Call the function:
690  AString Line1, Line2, Line3, Line4;
691  bool res = Self->GetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4);
692 
693  // Push the returned values:
694  L.Push(res);
695  if (res)
696  {
697  L.Push(Line1, Line2, Line3, Line4);
698  return 5;
699  }
700  return 1;
701 }
702 
703 
704 
705 
706 
707 static int tolua_cWorld_PrepareChunk(lua_State * tolua_S)
708 {
709  /* Function signature:
710  World:PrepareChunk(ChunkX, ChunkZ, Callback)
711  */
712 
713  // Check the param types:
714  cLuaState L(tolua_S);
715  if (
716  !L.CheckParamUserType (1, "cWorld") ||
717  !L.CheckParamNumber (2, 3) ||
719  )
720  {
721  return 0;
722  }
723 
724  // Wrap the Lua callback inside a C++ callback class:
725  class cCallback:
726  public cChunkCoordCallback
727  {
728  public:
729  // cChunkCoordCallback override:
730  virtual void Call(cChunkCoords a_Coords, bool a_IsSuccess) override
731  {
732  m_LuaCallback.Call(a_Coords.m_ChunkX, a_Coords.m_ChunkZ, a_IsSuccess);
733  }
734 
735  cLuaState::cOptionalCallback m_LuaCallback;
736  };
737 
738  // Read the params:
739  cWorld * world = nullptr;
740  int chunkX = 0;
741  int chunkZ = 0;
742  auto Callback = cpp14::make_unique<cCallback>();
743  L.GetStackValues(1, world, chunkX, chunkZ, Callback->m_LuaCallback);
744  if (world == nullptr)
745  {
746  LOGWARNING("World:PrepareChunk(): invalid world parameter");
747  L.LogStackTrace();
748  return 0;
749  }
750 
751  // Call the chunk preparation:
752  world->PrepareChunk(chunkX, chunkZ, std::move(Callback));
753  return 0;
754 }
755 
756 
757 
758 
759 
760 static int tolua_cWorld_QueueTask(lua_State * tolua_S)
761 {
762  // Function signature:
763  // World:QueueTask(Callback)
764 
765  // Retrieve the args:
766  cLuaState L(tolua_S);
767  if (
768  !L.CheckParamUserType(1, "cWorld") ||
769  !L.CheckParamFunction(2)
770  )
771  {
772  return 0;
773  }
774  cWorld * World;
776  if (!L.GetStackValues(1, World, Task))
777  {
778  return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Cannot read parameters");
779  }
780  if (World == nullptr)
781  {
782  return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Not called on an object instance");
783  }
784  if (!Task->IsValid())
785  {
786  return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Could not store the callback parameter");
787  }
788 
789  World->QueueTask([Task](cWorld & a_World)
790  {
791  Task->Call(&a_World);
792  }
793  );
794  return 0;
795 }
796 
797 
798 
799 
800 
801 static int tolua_cWorld_SetSignLines(lua_State * tolua_S)
802 {
803  // Exported manually, because tolua would generate useless additional return values (a_Line1 .. a_Line4)
804 
805  // Check params:
806  cLuaState L(tolua_S);
807  if (
808  !L.CheckParamUserType(1, "cWorld") ||
809  !L.CheckParamNumber(2, 4) ||
810  !L.CheckParamString(5, 8) ||
811  !L.CheckParamEnd(9)
812  )
813  {
814  return 0;
815  }
816 
817  // Get params:
818  cWorld * Self = nullptr;
819  int BlockX = 0;
820  int BlockY = 0;
821  int BlockZ = 0;
822  AString Line1, Line2, Line3, Line4;
823  L.GetStackValues(1, Self, BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4);
824  if (Self == nullptr)
825  {
826  return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
827  }
828 
829  // Call the function:
830  bool res = Self->SetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4);
831 
832  // Push the returned values:
833  L.Push(res);
834  return 1;
835 }
836 
837 
838 
839 
840 
841 static int tolua_cWorld_ScheduleTask(lua_State * tolua_S)
842 {
843  // Function signature:
844  // World:ScheduleTask(NumTicks, Callback)
845 
846  // Retrieve the args:
847  cLuaState L(tolua_S);
848  if (
849  !L.CheckParamUserType(1, "cWorld") ||
850  !L.CheckParamNumber (2) ||
851  !L.CheckParamFunction(3)
852  )
853  {
854  return 0;
855  }
856  cWorld * World;
857  int NumTicks;
858  auto Task = std::make_shared<cLuaState::cCallback>();
859  if (!L.GetStackValues(1, World, NumTicks, Task))
860  {
861  return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Cannot read parameters");
862  }
863  if (World == nullptr)
864  {
865  return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Not called on an object instance");
866  }
867  if (!Task->IsValid())
868  {
869  return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Could not store the callback parameter");
870  }
871 
872  World->ScheduleTask(NumTicks, [Task](cWorld & a_World)
873  {
874  Task->Call(&a_World);
875  }
876  );
877  return 0;
878 }
879 
880 
881 
882 
883 
884 static int tolua_cWorld_SpawnSplitExperienceOrbs(lua_State* tolua_S)
885 {
886  cLuaState L(tolua_S);
887  if (
888  !L.CheckParamSelf("cWorld") ||
889  !L.CheckParamUserType(2, "Vector3<double>") ||
890  !L.CheckParamNumber(3) ||
891  !L.CheckParamEnd(4)
892  )
893  {
894  return 0;
895  }
896 
897  cWorld * self = nullptr;
898  Vector3d * Position = nullptr;
899  int Reward;
900  L.GetStackValues(1, self, Position, Reward);
901  if (self == nullptr)
902  {
903  tolua_error(tolua_S, "Invalid 'self' in function 'SpawnSplitExperienceOrbs'", nullptr);
904  return 0;
905  }
906  if (Position == nullptr)
907  {
908  tolua_error(tolua_S, "Error in function 'SpawnSplitExperienceOrbs' arg #2. Value must not be nil.", nullptr);
909  return 0;
910  }
911 
912  // Execute and push result:
913  L.Push(self->SpawnExperienceOrb(Position->x, Position->y, Position->z, Reward));
914  return 1;
915 }
916 
917 
918 
919 
920 
921 static int tolua_cWorld_TryGetHeight(lua_State * tolua_S)
922 {
923  /* Exported manually, because tolua would require the out-only param a_Height to be used when calling
924  Function signature: world:TryGetHeight(a_World, a_BlockX, a_BlockZ) -> IsValid, Height
925  */
926 
927  // Check params:
928  cLuaState L(tolua_S);
929  if (
930  !L.CheckParamUserType(1, "cWorld") ||
931  !L.CheckParamNumber(2, 3) ||
932  !L.CheckParamEnd(4)
933  )
934  {
935  return 0;
936  }
937 
938  // Get params:
939  cWorld * self = nullptr;
940  int BlockX = 0;
941  int BlockZ = 0;
942  L.GetStackValues(1, self, BlockX, BlockZ);
943  if (self == nullptr)
944  {
945  tolua_error(tolua_S, "Invalid 'self' in function 'TryGetHeight'", nullptr);
946  return 0;
947  }
948 
949  // Call the implementation:
950  int Height = 0;
951  bool res = self->TryGetHeight(BlockX, BlockZ, Height);
952  L.Push(res);
953  if (res)
954  {
955  L.Push(Height);
956  return 2;
957  }
958  return 1;
959 }
960 
961 
962 
963 
964 
965 void cManualBindings::BindWorld(lua_State * tolua_S)
966 {
967  tolua_beginmodule(tolua_S, nullptr);
968  tolua_beginmodule(tolua_S, "cWorld");
969  tolua_function(tolua_S, "BroadcastBlockAction", tolua_cWorld_BroadcastBlockAction);
970  tolua_function(tolua_S, "BroadcastSoundEffect", tolua_cWorld_BroadcastSoundEffect);
971  tolua_function(tolua_S, "BroadcastSoundParticleEffect", tolua_cWorld_BroadcastSoundParticleEffect);
972  tolua_function(tolua_S, "BroadcastParticleEffect", tolua_cWorld_BroadcastParticleEffect);
973  tolua_function(tolua_S, "ChunkStay", tolua_cWorld_ChunkStay);
974  tolua_function(tolua_S, "DoExplosionAt", tolua_cWorld_DoExplosionAt);
975  tolua_function(tolua_S, "DoWithBeaconAt", DoWithXYZ<cWorld, cBeaconEntity, &cWorld::DoWithBeaconAt>);
976  tolua_function(tolua_S, "DoWithBedAt", DoWithXYZ<cWorld, cBedEntity, &cWorld::DoWithBedAt>);
977  tolua_function(tolua_S, "DoWithBlockEntityAt", DoWithXYZ<cWorld, cBlockEntity, &cWorld::DoWithBlockEntityAt>);
978  tolua_function(tolua_S, "DoWithBrewingstandAt", DoWithXYZ<cWorld, cBrewingstandEntity, &cWorld::DoWithBrewingstandAt>);
979  tolua_function(tolua_S, "DoWithChestAt", DoWithXYZ<cWorld, cChestEntity, &cWorld::DoWithChestAt>);
980  tolua_function(tolua_S, "DoWithCommandBlockAt", DoWithXYZ<cWorld, cCommandBlockEntity, &cWorld::DoWithCommandBlockAt>);
981  tolua_function(tolua_S, "DoWithDispenserAt", DoWithXYZ<cWorld, cDispenserEntity, &cWorld::DoWithDispenserAt>);
982  tolua_function(tolua_S, "DoWithDropSpenserAt", DoWithXYZ<cWorld, cDropSpenserEntity, &cWorld::DoWithDropSpenserAt>);
983  tolua_function(tolua_S, "DoWithDropperAt", DoWithXYZ<cWorld, cDropperEntity, &cWorld::DoWithDropperAt>);
984  tolua_function(tolua_S, "DoWithEntityByID", DoWithID< cWorld, cEntity, &cWorld::DoWithEntityByID>);
985  tolua_function(tolua_S, "DoWithFlowerPotAt", DoWithXYZ<cWorld, cFlowerPotEntity, &cWorld::DoWithFlowerPotAt>);
986  tolua_function(tolua_S, "DoWithFurnaceAt", DoWithXYZ<cWorld, cFurnaceEntity, &cWorld::DoWithFurnaceAt>);
987  tolua_function(tolua_S, "DoWithMobHeadAt", DoWithXYZ<cWorld, cMobHeadEntity, &cWorld::DoWithMobHeadAt>);
988  tolua_function(tolua_S, "DoWithNearestPlayer", tolua_cWorld_DoWithNearestPlayer);
989  tolua_function(tolua_S, "DoWithNoteBlockAt", DoWithXYZ<cWorld, cNoteEntity, &cWorld::DoWithNoteBlockAt>);
990  tolua_function(tolua_S, "DoWithPlayer", DoWith< cWorld, cPlayer, &cWorld::DoWithPlayer>);
991  tolua_function(tolua_S, "DoWithPlayerByUUID", tolua_cWorld_DoWithPlayerByUUID);
992  tolua_function(tolua_S, "FindAndDoWithPlayer", DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>);
993  tolua_function(tolua_S, "ForEachBlockEntityInChunk", ForEachInChunk<cWorld, cBlockEntity, &cWorld::ForEachBlockEntityInChunk>);
994  tolua_function(tolua_S, "ForEachBrewingstandInChunk", ForEachInChunk<cWorld, cBrewingstandEntity, &cWorld::ForEachBrewingstandInChunk>);
995  tolua_function(tolua_S, "ForEachChestInChunk", ForEachInChunk<cWorld, cChestEntity, &cWorld::ForEachChestInChunk>);
996  tolua_function(tolua_S, "ForEachEntity", ForEach< cWorld, cEntity, &cWorld::ForEachEntity>);
997  tolua_function(tolua_S, "ForEachEntityInBox", ForEachInBox< cWorld, cEntity, &cWorld::ForEachEntityInBox>);
998  tolua_function(tolua_S, "ForEachEntityInChunk", ForEachInChunk<cWorld, cEntity, &cWorld::ForEachEntityInChunk>);
999  tolua_function(tolua_S, "ForEachFurnaceInChunk", ForEachInChunk<cWorld, cFurnaceEntity, &cWorld::ForEachFurnaceInChunk>);
1000  tolua_function(tolua_S, "ForEachLoadedChunk", tolua_cWorld_ForEachLoadedChunk);
1001  tolua_function(tolua_S, "ForEachPlayer", ForEach< cWorld, cPlayer, &cWorld::ForEachPlayer>);
1002  tolua_function(tolua_S, "GetBlockInfo", tolua_cWorld_GetBlockInfo);
1003  tolua_function(tolua_S, "GetBlockTypeMeta", tolua_cWorld_GetBlockTypeMeta);
1004  tolua_function(tolua_S, "GetSignLines", tolua_cWorld_GetSignLines);
1005  tolua_function(tolua_S, "PrepareChunk", tolua_cWorld_PrepareChunk);
1006  tolua_function(tolua_S, "QueueTask", tolua_cWorld_QueueTask);
1007  tolua_function(tolua_S, "ScheduleTask", tolua_cWorld_ScheduleTask);
1008  tolua_function(tolua_S, "SetSignLines", tolua_cWorld_SetSignLines);
1009  tolua_function(tolua_S, "SpawnSplitExperienceOrbs", tolua_cWorld_SpawnSplitExperienceOrbs);
1010  tolua_function(tolua_S, "TryGetHeight", tolua_cWorld_TryGetHeight);
1011  tolua_endmodule(tolua_S);
1012  tolua_endmodule(tolua_S);
1013 }
1014 
1015 
1016 
1017 
static bool CheckParamVectorOr3Numbers(cLuaState &L, const char *a_VectorName, int a_Index, int &a_NextIndex)
Check that a Lua parameter is either a vector or 3 numbers in sequence.
bool CheckParamString(int a_StartParam, int a_EndParam=-1)
Returns true if the specified parameters on the stack are strings; also logs warning if not...
Definition: LuaState.cpp:1717
bool ForEachLoadedChunk(cFunctionRef< bool(int, int)> a_Callback)
Calls the callback for each loaded chunk.
Definition: World.cpp:2979
T x
Definition: Vector3.h:17
static int tolua_cWorld_DoWithNearestPlayer(lua_State *tolua_S)
Same thing as cCallback, but GetStackValue() won&#39;t fail if the callback value is nil.
Definition: LuaState.h:334
bool Call(const FnT &a_Function, Args &&...args)
Call the specified Lua function.
Definition: LuaState.h:744
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:42
static int tolua_cWorld_GetBlockInfo(lua_State *tolua_S)
static int tolua_cWorld_BroadcastSoundEffect(lua_State *tolua_S)
bool SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AString &a_Line1, const AString &a_Line2, const AString &a_Line3, const AString &a_Line4, cPlayer *a_Player=nullptr)
Sets the sign text, asking plugins for permission first.
Definition: World.cpp:2852
#define LOGWARN
Definition: LoggerSimple.h:43
bool CheckParamNumber(int a_StartParam, int a_EndParam=-1)
Returns true if the specified parameters on the stack are numbers; also logs warning if not...
Definition: LuaState.cpp:1651
static bool GetStackVectorOr3Numbers(cLuaState &L, int a_Index, Vector3< T > &a_Return)
Get a vector from the stack, which may be represented in lua as either a Vector3<T> or 3 numbers...
Definition: Player.h:27
bool CheckParamSelf(const char *a_SelfClassName)
Returns true if the first parameter is an instance of the expected class name.
Definition: LuaState.cpp:1880
bool CheckParamBool(int a_StartParam, int a_EndParam=-1)
Returns true if the specified parameters on the stack are bools; also logs warning if not...
Definition: LuaState.cpp:1684
static int tolua_cWorld_ChunkStay(lua_State *tolua_S)
void LogStackTrace(int a_StartingDepth=0)
Logs all items in the current stack trace to the server console.
Definition: LuaState.cpp:1980
bool GetStackValue(int a_StackPos, AString &a_Value)
Definition: LuaState.cpp:1105
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:45
Encapsulates a Lua state and provides some syntactic sugar for common operations. ...
Definition: LuaState.h:57
T y
Definition: Vector3.h:17
bool CheckParamFunctionOrNil(int a_StartParam, int a_EndParam=-1)
Returns true if the specified parameters on the stack are functions or nils; also logs warning if not...
Definition: LuaState.cpp:1786
T z
Definition: Vector3.h:17
void QueueTask(std::function< void(cWorld &)> a_Task)
Queues a task onto the tick thread.
Definition: World.cpp:3010
static int tolua_cWorld_ScheduleTask(lua_State *tolua_S)
bool CheckParamTable(int a_StartParam, int a_EndParam=-1)
Returns true if the specified parameters on the stack are tables; also logs warning if not...
Definition: LuaState.cpp:1615
void PrepareChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr< cChunkCoordCallback > a_CallAfter={})
Queues the chunk for preparing - making sure that it&#39;s generated and lit.
Definition: World.cpp:2834
virtual void BroadcastSoundEffect(const AString &a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle *a_Exclude=nullptr) override
Definition: UUID.h:10
bool CheckParamUserType(int a_StartParam, const char *a_UserType, int a_EndParam=-1)
Returns true if the specified parameters on the stack are of the specified usertype; also logs warnin...
Definition: LuaState.cpp:1582
Utilities to allow casting a cWorld to one of its interfaces without including World.h.
Definition: OpaqueWorld.h:12
bool CheckParamEnd(int a_Param)
Returns true if the specified parameter on the stack is nil (indicating an end-of-parameters) ...
Definition: LuaState.cpp:1860
bool GetBlockTypeMeta(Vector3i a_BlockPos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta)
Retrieves the block type and meta at the specified coords.
Definition: World.cpp:1909
virtual void BroadcastSoundParticleEffect(const EffectID a_EffectID, Vector3i a_SrcPos, int a_Data, const cClientHandle *a_Exclude=nullptr) override
bool GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString &a_Line1, AString &a_Line2, AString &a_Line3, AString &a_Line4)
Retrieves the test on the sign at the specified coords; returns false if there&#39;s no sign at those coo...
Definition: World.cpp:1549
Definition: World.h:65
static int tolua_cWorld_GetSignLines(lua_State *tolua_S)
std::unique_ptr< cOptionalCallback > cOptionalCallbackPtr
Definition: LuaState.h:358
bool IsValid(void) const
Returns true if the reference is valid.
Definition: LuaState.h:184
static int tolua_cWorld_SpawnSplitExperienceOrbs(lua_State *tolua_S)
static int tolua_cWorld_BroadcastBlockAction(lua_State *tolua_S)
virtual void BroadcastBlockAction(Vector3i a_BlockPos, Byte a_Byte1, Byte a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle *a_Exclude=nullptr) override
bool CheckParamFunction(int a_StartParam, int a_EndParam=-1)
Returns true if the specified parameters on the stack are functions; also logs warning if not...
Definition: LuaState.cpp:1753
std::unique_ptr< cStackTable > cStackTablePtr
Definition: LuaState.h:543
bool DoWithNearestPlayer(Vector3d a_Pos, double a_RangeLimit, cPlayerListCallback a_Callback, bool a_CheckLineOfSight=true, bool a_IgnoreSpectator=true)
Calls the callback for nearest player for given position, Returns false if player not found...
Definition: World.cpp:2639
#define ASSERT(x)
Definition: Globals.h:335
static int tolua_cWorld_TryGetHeight(lua_State *tolua_S)
void LOGWARNING(const char *a_Format, fmt::ArgList a_ArgList)
Definition: Logger.cpp:174
static int tolua_cWorld_SetSignLines(lua_State *tolua_S)
Used for storing references to object in the global registry.
Definition: LuaState.h:161
void ScheduleTask(int a_DelayTicks, std::function< void(cWorld &)> a_Task)
Queues a lambda task onto the tick thread, with the specified delay.
Definition: World.cpp:3020
int m_ChunkZ
Definition: ChunkDef.h:60
void LogStackValues(const char *a_Header=nullptr)
Logs all the elements&#39; types on the API stack, with an optional header for the listing.
Definition: LuaState.cpp:2265
static const cRet Return
Definition: LuaState.h:446
virtual void BroadcastParticleEffect(const AString &a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, const cClientHandle *a_Exclude=nullptr) override
eExplosionSource
The source of an explosion.
Definition: BlockID.h:1202
static int tolua_cWorld_DoWithPlayerByUUID(lua_State *tolua_S)
cChunkMap * GetChunkMap(void)
Definition: World.h:1044
int m_ChunkX
Definition: ChunkDef.h:59
std::string AString
Definition: StringUtils.h:13
static int tolua_cWorld_QueueTask(lua_State *tolua_S)
static int tolua_cWorld_ForEachLoadedChunk(lua_State *tolua_S)
Interface class used as a callback for operations that involve chunk coords.
Definition: ChunkDef.h:610
signed int Int32
Definition: Globals.h:108
virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void *a_SourceData) override
Does an explosion with the specified strength at the specified coordinates.
Definition: World.cpp:1399
Definition: Entity.h:73
bool IsParamUserType(int a_Param, AString a_UserType)
Definition: LuaState.cpp:1930
bool DoWithPlayerByUUID(const cUUID &a_PlayerUUID, cPlayerListCallback a_Callback)
Finds the player over his uuid and calls the callback.
Definition: World.cpp:2622
virtual void Call(cChunkCoords a_Coords, bool a_IsSuccess)=0
Called with the chunk&#39;s coords, and an optional operation status flag for operations that support it...
bool GetBlockInfo(Vector3i a_BlockPos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_Meta, NIBBLETYPE &a_SkyLight, NIBBLETYPE &a_BlockLight)
Queries the whole block specification from the world.
Definition: World.cpp:1918
static int tolua_cWorld_DoExplosionAt(lua_State *tolua_S)
bool GetStackValues(int a_StartStackPos, Arg1 &&a_Arg1, Args &&...args)
Retrieves a list of values from the Lua stack, starting at the specified index.
Definition: LuaState.h:759
static int tolua_cWorld_GetBlockTypeMeta(lua_State *tolua_S)
unsigned char Byte
Definition: Globals.h:117
static int tolua_cWorld_PrepareChunk(lua_State *tolua_S)
void Push(Arg1 &&a_Arg1, Arg2 &&a_Arg2, Args &&...a_Args)
Pushes multiple arguments onto the Lua stack.
Definition: LuaState.h:605
std::shared_ptr< cCallback > cCallbackSharedPtr
Definition: LuaState.h:329
bool CheckParamUUID(int a_StartParam, int a_EndParam=-1)
Returns true if the specified parameters on the stack are UUIDs; also logs warning if not Accepts eit...
Definition: LuaState.cpp:1819
bool IsNil() const
Returns true if this contains the "nil" UUID with all bits set to 0.
Definition: UUID.h:30
static int tolua_cWorld_BroadcastSoundParticleEffect(lua_State *tolua_S)
static int tolua_cWorld_BroadcastParticleEffect(lua_State *tolua_S)
int ApiParamError(fmt::StringRef a_Msg)
Prints the message, prefixed with the current function name, then logs the stack contents and raises ...
Definition: LuaState.cpp:2007