@@ -651,38 +651,51 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
651
651
INodeDefManager *ndef = getServer (L)->ndef ();
652
652
v3s16 minp = read_v3s16 (L, 1 );
653
653
v3s16 maxp = read_v3s16 (L, 2 );
654
+ sortBoxVerticies (minp, maxp);
655
+
656
+ v3s16 cube = maxp - minp + 1 ;
657
+
658
+ /* Limit for too large areas, assume default values
659
+ * and give tolerances of 1 node on each side
660
+ * (chunksize * MAP_BLOCKSIZE + 2)^3 = 551368
661
+ */
662
+ if ((u64)cube.X * (u64)cube.Y * (u64)cube.Z > 551368 ) {
663
+ luaL_error (L, " find_nodes_in_area(): area volume"
664
+ " exceeds allowed value of 551368" );
665
+ return 0 ;
666
+ }
667
+
654
668
std::set<content_t > filter;
655
- if (lua_istable (L, 3 )) {
656
- int table = 3 ;
669
+ if (lua_istable (L, 3 )) {
657
670
lua_pushnil (L);
658
- while (lua_next (L, table ) != 0 ) {
671
+ while (lua_next (L, 3 ) != 0 ) {
659
672
// key at index -2 and value at index -1
660
673
luaL_checktype (L, -1 , LUA_TSTRING);
661
674
ndef->getIds (lua_tostring (L, -1 ), filter);
662
675
// removes value, keeps key for next iteration
663
676
lua_pop (L, 1 );
664
677
}
665
- } else if (lua_isstring (L, 3 )) {
678
+ } else if (lua_isstring (L, 3 )) {
666
679
ndef->getIds (lua_tostring (L, 3 ), filter);
667
680
}
668
681
669
- std::map <content_t , u16 > individual_count;
682
+ std::unordered_map <content_t , u32 > individual_count;
670
683
671
684
lua_newtable (L);
672
685
u64 i = 0 ;
673
686
for (s16 x = minp.X ; x <= maxp.X ; x++)
674
- for (s16 y = minp.Y ; y <= maxp.Y ; y++)
675
- for (s16 z = minp.Z ; z <= maxp.Z ; z++) {
676
- v3s16 p (x, y, z);
677
- content_t c = env->getMap ().getNodeNoEx (p).getContent ();
678
- if (filter.count (c) != 0 ) {
679
- push_v3s16 (L, p);
680
- lua_rawseti (L, -2 , ++i);
681
- individual_count[c]++;
682
- }
687
+ for (s16 y = minp.Y ; y <= maxp.Y ; y++)
688
+ for (s16 z = minp.Z ; z <= maxp.Z ; z++) {
689
+ v3s16 p (x, y, z);
690
+ content_t c = env->getMap ().getNodeNoEx (p).getContent ();
691
+ if (filter.count (c) != 0 ) {
692
+ push_v3s16 (L, p);
693
+ lua_rawseti (L, -2 , ++i);
694
+ individual_count[c]++;
695
+ }
683
696
}
684
697
lua_newtable (L);
685
- for (std::set<content_t >::iterator it = filter.begin ();
698
+ for (std::set<content_t >::const_iterator it = filter.begin ();
686
699
it != filter.end (); ++it) {
687
700
lua_pushnumber (L, individual_count[*it]);
688
701
lua_setfield (L, -2 , ndef->get (*it).name .c_str ());
@@ -706,12 +719,25 @@ int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
706
719
INodeDefManager *ndef = getServer (L)->ndef ();
707
720
v3s16 minp = read_v3s16 (L, 1 );
708
721
v3s16 maxp = read_v3s16 (L, 2 );
722
+ sortBoxVerticies (minp, maxp);
723
+
724
+ v3s16 cube = maxp - minp + 1 ;
725
+
726
+ /* Limit for too large areas, assume default values
727
+ * and give tolerances of 1 node on each side
728
+ * (chunksize * MAP_BLOCKSIZE + 2)^3 = 551368
729
+ */
730
+ if ((u64)cube.X * (u64)cube.Y * (u64)cube.Z > 551368 ) {
731
+ luaL_error (L, " find_nodes_in_area_under_air(): area volume"
732
+ " exceeds allowed value of 551368" );
733
+ return 0 ;
734
+ }
735
+
709
736
std::set<content_t > filter;
710
737
711
738
if (lua_istable (L, 3 )) {
712
- int table = 3 ;
713
739
lua_pushnil (L);
714
- while (lua_next (L, table ) != 0 ) {
740
+ while (lua_next (L, 3 ) != 0 ) {
715
741
// key at index -2 and value at index -1
716
742
luaL_checktype (L, -1 , LUA_TSTRING);
717
743
ndef->getIds (lua_tostring (L, -1 ), filter);
@@ -732,7 +758,7 @@ int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
732
758
for (; y <= maxp.Y ; y++) {
733
759
v3s16 psurf (x, y + 1 , z);
734
760
content_t csurf = env->getMap ().getNodeNoEx (psurf).getContent ();
735
- if (c != CONTENT_AIR && csurf == CONTENT_AIR &&
761
+ if (c != CONTENT_AIR && csurf == CONTENT_AIR &&
736
762
filter.count (c) != 0 ) {
737
763
push_v3s16 (L, v3s16 (x, y, z));
738
764
lua_rawseti (L, -2 , ++i);
0 commit comments