Vars in command don't reset after command?

Discussion in 'Plugin Development' started by bfgbfggf, Aug 10, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    bfgbfggf

    I have something like that:
    Code:
    public class Define implements CommandExecutor {
        private Location p1, p2, p3, p4, loc, loc2, copy;
        private Player player;
        // private String playerName;
        private int size;
        private int[] dir;
        private int[] sizes = { 22, 48, 65, 139, 285, 502 };
        private boolean isBonus;
        private World world;
        private Block block, toRemove;
        final private BaseBlock[] fenceBlocks = { new BaseBlock(139, 0),
                new BaseBlock(139, 1), new BaseBlock(121, 0) };
    //Rest of code
    But I have one problem.... in some place I have debug messages with p1,p2,p3,p4. And when I type a command I still get locations from previous command ;/
    Why? Variables don't reset after command? that feature of static but I don't use private static Location ;/ So... where is problem :(
     
  2. Offline

    LinearLogic

    The scope of the variables in question is class-wide, so they'll persist outside of the onCommand(...) method. You need to update them in your onCommand block; the variables aren't automatically updated simply because you implement CommandExecutor.
     
  3. Offline

    bfgbfggf

    Aw... so i must reset ALL values ? ;/
    p1=nul;
    p2=null;
    etc... ?
     
  4. Offline

    LinearLogic

    No need. Unless you absolutely need to save the variables listed above, limit their scope to the onCommand(...) method. And even if they are to be saved, I can't imagine why they'd ever need to be reset - only updated.
     
  5. Offline

    bfgbfggf

    Most of that variables will be updated in code but p1,p2,p3 p4 is updated in loop end:
    if p1 is null then set p1 to current loc else if p2 is null then set p1 to current loc else if p3... :p So I can't update it in code.
     
  6. Offline

    LinearLogic

    Can you paste your CommandExecutor in its entirety?
     
  7. Offline

    bfgbfggf

    eeem.... ok :D but my code don't work anyway xD
    That code to get 4 corners of Region (must have full fence). But I have problems with one or two walls ;/

    Code:java
    1.  
    2. package com.gmail.bukkitSmerf.cmd;
    3.  
    4. import java.util.ArrayList;
    5. import java.util.List;
    6.  
    7. import org.bukkit.Location;
    8. import org.bukkit.World;
    9. import org.bukkit.block.Block;
    10. import org.bukkit.command.Command;
    11. import org.bukkit.command.CommandExecutor;
    12. import org.bukkit.command.CommandSender;
    13. import org.bukkit.entity.Player;
    14. import com.gmail.bukkitSmerf.minelive.Util;
    15. import com.sk89q.worldedit.blocks.BaseBlock;
    16.  
    17. public class Define implements CommandExecutor {
    18. private Location p1, p2, p3, p4, loc, loc2, copy;
    19. private Player player;
    20. // private String playerName;
    21. private int size;
    22. private int wall = 0;
    23. private int[] dir;
    24. private int[] sizes = { 22, 48, 65, 139, 285, 502 };
    25. private boolean isBonus;
    26. private World world;
    27. private Block block, toRemove;
    28. final private BaseBlock[] fenceBlocks = { new BaseBlock(139, 0),
    29. new BaseBlock(139, 1), new BaseBlock(121, 0) };
    30. private List<int[]> usedDir = new ArrayList<int[]>();
    31.  
    32. private boolean noRegionReturn() {
    33. Util.sendMsg(
    34. "&4Nie wykryto wolnej dzialki.\n&cMusisz stanac obok dzialki i patrzac sie na plot wpisac ta komende. :)\n&bJesli jestes pewien ze wszystko robisz dobrze a blad dalej wystepuje napisz do &aBukkit&9Smerf&b-y",
    35. player);
    36. return true;
    37. }
    38.  
    39. private void resetLoc() {
    40. loc2 = copy.clone();
    41. }
    42.  
    43. private Location add(int[] i, boolean multi) {
    44. if (!multi)
    45. return loc.clone().add(i[0], (i.length == 2) ? 0 : i[1],
    46. (i.length == 2) ? i[1] : i[2]);
    47. else {
    48. return (loc2.add(i[0], (i.length == 2) ? 0 : i[1],
    49. (i.length == 2) ? i[1] : i[2]));
    50. }
    51. }
    52.  
    53. private boolean isValid() {
    54. for (BaseBlock vaild : fenceBlocks) {
    55. if (block.getTypeId() == vaild.getId()
    56. && block.getData() == vaild.getData())
    57. return true;
    58. }
    59. return false;
    60. }
    61.  
    62. private boolean checkBlock(Block block) {
    63. if (this.block.getTypeId() == block.getTypeId()
    64. && this.block.getData() == block.getData())
    65. return true;
    66. return false;
    67. }
    68.  
    69. // I don't know why but usedDir.contains don't work.
    70. private boolean isBlocked(int[] dir) {
    71. for (int[] block : usedDir)
    72. if (block[0] == dir[0] && block[1] == dir[1] && block[2] == dir[2])
    73. return true;
    74. return false;
    75. }
    76.  
    77. private int[] getDir() {
    78. int[] result;
    79. String kier = "";
    80. for (int[] lol : usedDir) {
    81. kier += "[" + lol[0] + ", " + lol[1] + ", " + lol[2] + "], ";
    82. }
    83.  
    84. //debug
    85. Util.sendMsg("Wybieranie kierunku: (Zablokowane: " + kier + ")", player);
    86. if (checkBlock(add(new int[] { 1, 0 }, false).getBlock())
    87. && checkBlock(add(new int[] { -1, 0 }, false).getBlock())) {
    88. result = new int[] { 0, 1, 1 };
    89. usedDir.add(result);
    90. usedDir.add(new int[] { 0, 1, 0 });
    91. usedDir.add(new int[] { 0, 0, 1 });
    92.  
    93. //debug
    94. Util.sendMsg("wybrano: [" + result[0] + ", " + result[1] + ", "
    95. + result[2] + "]1, ", player);
    96. return result;
    97. } else if (checkBlock(add(new int[] { 1, 0 }, false).getBlock())
    98. && (checkBlock(add(new int[] { 0, 1 }, false).getBlock()) || checkBlock(add(
    99. new int[] { 0, -1 }, false).getBlock()))) {
    100. result = new int[] { 0, 0, 1 };
    101. if (!isBlocked(result)) {
    102. usedDir.add(result);
    103. usedDir.add(new int[] { 0, 1, 0 });
    104. } else {
    105. if (checkBlock(add(new int[] { 0, 1 }, false).getBlock())) {
    106. result = new int[] { 1, 0, 1 };
    107. } else {
    108. result = new int[] { 1, 1, 0 };
    109. }
    110.  
    111. }
    112.  
    113. //debug
    114. Util.sendMsg("wybrano: [" + result[0] + ", " + result[1] + ", "
    115. + result[2] + "]2, ", player);
    116. return result;
    117. } else if (checkBlock(add(new int[] { -1, 0 }, false).getBlock())
    118. && (checkBlock(add(new int[] { 0, 1 }, false).getBlock()) || checkBlock(add(
    119. new int[] { 0, -1 }, false).getBlock()))) {
    120. result = new int[] { 0, 1, 0 };
    121. if (!isBlocked(result)) {
    122. usedDir.add(result);
    123. usedDir.add(new int[] { 0, 1, 0 });
    124. } else {
    125. if (checkBlock(add(new int[] { 0, 1 }, false).getBlock())) {
    126. result = new int[] { 1, 0, 1 };
    127. } else {
    128. result = new int[] { 1, 1, 0 };
    129. }
    130. }
    131.  
    132. //debug
    133. Util.sendMsg("wybrano: [" + result[0] + ", " + result[1] + ", "
    134. + result[2] + "]3, ", player);
    135. return result;
    136. } else if (checkBlock(add(new int[] { 0, -1 }, false).getBlock())
    137. && checkBlock(add(new int[] { 0, 1 }, false).getBlock())) {
    138. result = new int[] { 1, 1, 1 };
    139. usedDir.add(result);
    140. usedDir.add(new int[] { 1, 1, 0 });
    141. usedDir.add(new int[] { 1, 0, 1 });
    142.  
    143. //debug
    144. Util.sendMsg("wybrano: [" + result[0] + ", " + result[1] + ", "
    145. + result[2] + "]4, ", player);
    146. return result;
    147. } else
    148. return null;
    149.  
    150. }
    151.  
    152. private boolean isValidSize() {
    153. for (int size : sizes)
    154. if (this.size == size)
    155. return true;
    156. return false;
    157. }
    158.  
    159. private boolean getWalls() {
    160. Util.sendMsg("3", player);
    161. for (wall = 1; wall < 5; wall++) {
    162.  
    163. //debug
    164. Util.sendMsg("4 + " + wall, player);
    165. dir = getDir();
    166. if (dir == null)
    167. return noRegionReturn();
    168. else if ((dir[1] + dir[2] != 2) && p1 == null) {
    169. usedDir.clear();
    170. p1 = loc;
    171. Util.sendMsg("LOL", player);
    172. continue;
    173. }
    174. boolean isZFade = (dir[0] == 1);
    175.  
    176. //debug
    177. Util.sendMsg("5 + DIR: " + dir[0] + "," + dir[1] + "," + dir[2]
    178. + ", " + isZFade, player);
    179. boolean next = false;
    180. for (int i = 1; i < 505; i++) {
    181. if (!next) {
    182. if (checkBlock(add(
    183. (isZFade) ? new int[] { 0, ((dir[1] == 0) ? 1 : -1) }
    184. : new int[] { ((dir[1] == 0) ? 1 : -1), 0 },
    185. true).getBlock())) {
    186. if (wall == 1)
    187. size++;
    188. } else {
    189. loc2.subtract(((isZFade) ? 0 : (dir[1] == 0) ? 1 : -1),
    190. 0, ((!isZFade) ? 0 : (dir[1] == 0) ? 1 : -1));
    191. if (p1 == null) {
    192. Util.sendMsg("LOL2", player);
    193. next = true;
    194. p1 = loc2.clone();
    195. continue;
    196. } else if (p2 == null) {
    197. p2 = loc2.clone();
    198. break;
    199. } else if (p3 == null) {
    200. p3 = loc2.clone();
    201. break;
    202. } else if (p4 == null) {
    203. p4 = loc2.clone();
    204. break;
    205. }
    206. }
    207. } else {
    208. resetLoc();
    209. if (checkBlock(add(
    210. (isZFade) ? new int[] { 0, ((dir[2] == 0) ? -1 : 1) }
    211. : new int[] { ((dir[2] == 0) ? -1 : 1), 0 },
    212. true).getBlock()))
    213. size++;
    214. else {
    215. p2 = loc2.clone();
    216. break;
    217. }
    218. }
    219. }
    220. loc = loc2.clone();
    221.  
    222. //debug
    223. Util.sendMsg("6" + size, player);
    224. if (wall == 1)
    225. if (!isValidSize())
    226. return noRegionReturn();
    227.  
    228. //debug
    229. Util.sendMsg("7", player);
    230. Util.sendMsg("Sciania gotowa", player);
    231. }
    232.  
    233. //debug
    234. Util.sendMsg("8", player);
    235. Util.sendMsg(
    236. "Wszystko gotowe!\nP1:"
    237. + ((p1 != null) ? p1.getBlockX() + ", "
    238. + p1.getBlockZ() : "")
    239. + "\nP2:"
    240. + ((p2 != null) ? p2.getBlockX() + ", "
    241. + p2.getBlockZ() : "")
    242. + "\nP3:"
    243. + ((p3 != null) ? p3.getBlockX() + ", "
    244. + p3.getBlockZ() : "")
    245. + "\nP4:"
    246. + ((p4 != null) ? p4.getBlockX() + ", "
    247. + p4.getBlockZ() : ""), player);
    248. return true;
    249. }
    250.  
    251. @Override
    252. public boolean onCommand(CommandSender sender, Command cmd, String label,
    253. String[] args) {
    254. if (sender instanceof Player) {
    255. isBonus = (args.length > 0 && (args[0].equalsIgnoreCase("true") || args[0]
    256. .equalsIgnoreCase("1"))) ? true : false;
    257. player = (Player) sender;
    258. // playerName = player.getName();
    259. block = player.getTargetBlock(null, 5);
    260. world = player.getWorld();
    261.  
    262. //debug
    263. Util.sendMsg("1", player);
    264. if ((block == null || block.getTypeId() == 1) || !isValid())
    265. return noRegionReturn();
    266. toRemove = block;
    267. size = 1;
    268. loc = block.getLocation();
    269. loc2 = loc.clone();
    270. copy = loc.clone();
    271.  
    272. //debug
    273. Util.sendMsg("2", player);
    274. getWalls();
    275. resetVar();
    276. }
    277. return true;
    278. }
    279.  
    280. private void resetVar() {
    281. p1 = null;
    282. p2 = null;
    283. p3 = null;
    284. p4 = null;
    285. loc = null;
    286. loc2 = null;
    287. copy = null;
    288. player = null;
    289. // playerName = null;
    290. size = 0;
    291. wall = 0;
    292. dir = null;
    293. isBonus = false;
    294. world = null;
    295. block = null;
    296. toRemove = null;
    297. usedDir.clear();
    298. }
    299. }
    300.  


    Sorry for some Polish language :p
     
  8. Offline

    LinearLogic

    When are values supposed to be reset? After a region has been completed?
     
  9. Offline

    bfgbfggf

    eeem All. But "sizes" and "fenceBlocks" don't must be reset.
    And my code don't work NOT becouse I can't reset it, But I just don't know how to write code for find and check that walls/corners :D
     
  10. Offline

    dunbaratu

    I suspect that the problem is this:

    You wrote code believing that it works like this:
    1. You tell the game "please use this class when someone types this command."
    2. A player types the command.
    3. The game creates an instance of your class.
    4. The game runs the onCommand() for that instance.
    5. The game throws away the instance of your class and it gets orphaned away.
    6. The player types another command.
    7. The game makes a new instance of your class.
    8. The game runs the onCommand() for that instance.
    9. The game throws away the instance of your class and it gets orphaned away.
    10. ...and so on...
    But in reality it works like this:
    1. You tell the game "please use this class when someone types this command."
    2. The game makes an instance of your class and stores it somewhere.
    3. A player types the command.
    4. The game runs the onCommand() in the instance it already made.
    5. The player types another command.
    6. The game runs the onCommand() in the instance it already made.
    7. ...and so on...
    The difference between static and non-static variables is whether there's a different copy per-instance, or just one copy globally that they all share access to. But in this case since there will only ever be one instance of your class anyway, you don't see any difference.

    I am NOT familiar with the details of how the system does what it does. I'm just guessing from what you're saying is happening that this is the reason.
     
  11. Offline

    LinearLogic

    Because the class implements CommandExecutor, this should never be the case. Rather, calling getCommand("define").setExecutor(new Define()) in the plugin's onEnable() method suffices.

    bfgbfggf
    One issue with tracking locations in the CommandExecutor itself is that you can only have data for one player at a time - it's not as if a new executor is instantiated every time a player runs a command. This is obviously problematic for a number of reasons, chief among which is that only one player can define a region at a time.
     
  12. Offline

    bfgbfggf

    hyyym. Can I create second class eg: UseDefine.class and in Define.class add
    new UseDefine(sender, args); (or new UseDefine().define(sender, args));
    And all code paste to UseDefine.class ?
    And that will by work for multiple players?

    That will be work? ;/

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 3, 2016
  13. Offline

    LinearLogic

    It's a stretch, and even in its best implementation will be inefficient and prone to malfunction. Why not just map the data to the appropriate player? Use a HashMap<Player, Location[]> where the Location array contains region boundaries.
     
  14. Offline

    bfgbfggf

    Hyyym... what can happen when 2 player use command? (PS: weee :D code work. create WordGuard region when player looking at fence and type "/define" command :D)
     
  15. Offline

    LinearLogic

    If multiple players run the command they'll all contribute to the creation of the same arena.
     
  16. Offline

    bfgbfggf

    hyym, but if I remove all Vars from eeem (I don't know how to name it) no-method space xD and put all to method and just send it to other methods then that problem will by fixed?
    eg:
    Code:
    class...
    private Location p1,p2,p3,p4;
    private boolean method1(){
    //some code using locations
    }
    public boolean onCommand(bla bla bla bla){
    // some code using locations
    method1();
    }
    Change to:

    Code:
    class...
    private boolean method1(Location p1, Location p2, Location p3, Location p4){
    //some code using locations
    }
    public boolean onCommand(bla bla bla bla){
    Location p1,p2,p3,p4;
    // some code using locations
    method1(p1 ,p2, p3, p4);
    }
     
  17. Offline

    LinearLogic

    If you put the variables in the onCommand(...) method, they'll expire as soon as the method returns, which renders them useless as a player can only define one corner of a region at once. I caved and wrote a class to show you what I've been trying to communicated. Note that only two regions are needed in order to create a region, and that only one of those locations needs to be stored.

    Code:java
    1. import java.util.HashMap;
    2.  
    3. import org.bukkit.ChatColor;
    4. import org.bukkit.Location;
    5. import org.bukkit.command.Command;
    6. import org.bukkit.command.CommandExecutor;
    7. import org.bukkit.command.CommandSender;
    8. import org.bukkit.entity.Player;
    9.  
    10. import com.sk89q.worldedit.BlockVector;
    11. import com.sk89q.worldguard.bukkit.WGBukkit;
    12. import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
    13.  
    14. public class Define implements CommandExecutor {
    15.  
    16. private HashMap<Player, Location> regionCorners;
    17.  
    18. @Override
    19. public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
    20. if (!(sender instanceof Player)) {
    21. sender.sendMessage(ChatColor.RED + "Only players can define regions!");
    22. return true;
    23. }
    24. Player player = (Player) sender;
    25. if (!regionCorners.containsKey(player)) { // Player is defining the first corner
    26. regionCorners.put(player, player.getLocation());
    27. player.sendMessage(ChatColor.GREEN + "Set the first region corner to your current location. " +
    28. "Repeat the command at another location to complete the region.");
    29. return true;
    30. }
    31. // Player has already defined one corner and is now setting the second
    32. Location corner1 = regionCorners.get(player),
    33. corner2 = player.getLocation();
    34. ProtectedCuboidRegion region = new ProtectedCuboidRegion("region_name_here", // Region name as a cmd arg?
    35. new BlockVector(corner1.getBlockX(), corner1.getBlockY(), corner1.getBlockZ()),
    36. new BlockVector(corner2.getBlockX(), corner2.getBlockY(), corner2.getBlockZ()));
    37. WGBukkit.getRegionManager(corner1.getWorld()).addRegion(region);
    38. player.sendMessage(ChatColor.GREEN + "Defined a new region!");
    39. return true;
    40. }
    41. }
    42.  
     
  18. Offline

    bfgbfggf

    Thanks for that, but that not code for me :D In my code player just type code in random place of fence and get new region. And that very important for me - region must by poly-region. I also creating command to auto-connecting regions so that will by only possible with poly-region.
    I just added boolean "isRun" and 2 players can't use that command. when I finish other code then I fix it :p
     
Thread Status:
Not open for further replies.

Share This Page