enebo/Purugin

not all block types are representable anymore

brandondrew opened this issue · 17 comments

I get this error when trying to use the cube command, taken (almost verbatim) from the examples:

[22:38:20 INFO]: iconoclast issued server command: /cube 1 andesite
[22:38:20 ERROR]: null
org.bukkit.command.CommandException: Unhandled exception executing 'cube 1 andesite' in org.jruby.proxy.org.bukkit.command.Command$Proxy1(cube)
    at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:144) ~[craftbukkit-1.8.8.jar:git-Bukkit-07c3001]
    at org.bukkit.craftbukkit.v1_8_R3.CraftServer.dispatchCommand(CraftServer.java:620) ~[craftbukkit-1.8.8.jar:git-Bukkit-07c3001]
    at net.minecraft.server.v1_8_R3.PlayerConnection.handleCommand(PlayerConnection.java:1106) [craftbukkit-1.8.8.jar:git-Bukkit-07c3001]
    at net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:966) [craftbukkit-1.8.8.jar:git-Bukkit-07c3001]
    at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(SourceFile:37) [craftbukkit-1.8.8.jar:git-Bukkit-07c3001]
    at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(SourceFile:9) [craftbukkit-1.8.8.jar:git-Bukkit-07c3001]
    at net.minecraft.server.v1_8_R3.PlayerConnectionUtils$1.run(SourceFile:13) [craftbukkit-1.8.8.jar:git-Bukkit-07c3001]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_65]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_65]
    at net.minecraft.server.v1_8_R3.SystemUtils.a(SourceFile:44) [craftbukkit-1.8.8.jar:git-Bukkit-07c3001]
    at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:673) [craftbukkit-1.8.8.jar:git-Bukkit-07c3001]
    at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:335) [craftbukkit-1.8.8.jar:git-Bukkit-07c3001]
    at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:629) [craftbukkit-1.8.8.jar:git-Bukkit-07c3001]
    at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:537) [craftbukkit-1.8.8.jar:git-Bukkit-07c3001]
    at java.lang.Thread.run(Thread.java:745) [?:1.8.0_65]
Caused by: org.jruby.exceptions.RaiseException: (NameError) no method 'setType' for arguments (org.jruby.RubySymbol) on Java::OrgBukkitCraftbukkitV1_8_R3Block::CraftBlock
    at RUBY.change_type(file:/Users/brandon/Code/Spigot/plugins/Purugin.jar!/bukkit/block/block.rb:118) ~[?:?]
    at RUBY.on_enable(/Users/brandon/Code/Spigot/plugins/builder.rb:24) ~[?:?]
    at org.jruby.RubyFixnum.times(org/jruby/RubyFixnum.java:275) ~[?:?]
    at RUBY.on_enable(/Users/brandon/Code/Spigot/plugins/builder.rb:23) ~[?:?]
    at org.jruby.RubyFixnum.times(org/jruby/RubyFixnum.java:275) ~[?:?]
    at RUBY.on_enable(/Users/brandon/Code/Spigot/plugins/builder.rb:21) ~[?:?]
    at org.jruby.RubyFixnum.times(org/jruby/RubyFixnum.java:275) ~[?:?]
    at RUBY.on_enable(/Users/brandon/Code/Spigot/plugins/builder.rb:19) ~[?:?]
    at org.jruby.RubyProc.call(org/jruby/RubyProc.java:271) ~[?:?]
    at RUBY.execute(file:/Users/brandon/Code/Spigot/plugins/Purugin.jar!/purugin/command.rb:45) ~[?:?]
    at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(SourceFile:37) ~[craftbukkit-1.8.8.jar:git-Bukkit-07c3001]
    at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(SourceFile:9) ~[craftbukkit-1.8.8.jar:git-Bukkit-07c3001]
    at net.minecraft.server.v1_8_R3.PlayerConnectionUtils$1.run(SourceFile:13) ~[craftbukkit-1.8.8.jar:git-Bukkit-07c3001]
    at net.minecraft.server.v1_8_R3.SystemUtils.a(SourceFile:44) ~[craftbukkit-1.8.8.jar:git-Bukkit-07c3001]

It works fine if you don't specify the material, but if you want anything besides glass, it fails.

(Here's the code, so that line numbers etc. are meaningful, but there are no significant changes from the example:)

class BuildingCommandPlugin
  include Purugin::Plugin, Purugin::Colors
  description 'Building Commands', 0.1

  def on_enable

    # usage example:
    # /cube 3 diorite
    public_command('cube', 'make n^3 cube of type', '/cube {dimension}') do |me, *args|
      dimensions = error? args[0].to_i, "Must specify an integer size"
      error? dimensions > 0, "Size must be an integer >0"

      type = args.length > 1 ? args[1].to_sym : :glass  # TODO default to what you're holding

      me.msg "You are trying to build with #{type.inspect}"
      z_block = error? me.target_block.block_at(:up), "No block targeted"

      me.msg "Creating cube of #{type} and size #{dimensions}"
      dimensions.times do
        y_block = z_block
        dimensions.times do
          x_block = y_block
          dimensions.times do
            x_block.change_type type
            x_block = x_block.block_at(:north)
          end
          y_block = y_block.block_at(:east)
        end
        z_block = z_block.block_at(:up)
      end
      me.msg "Done creating cube of #{type} and size #{dimensions}"
    end
  end
end

actually, hardcoding most materials other than glass seems to fail, at least with these:

  • andesite
  • diorite
  • granite

:dirt works, though.

Okay, dirt can be passed as an argument, so the problem is purely with some materials being accepted/recognized and others not being accepted/recognized.

diamond fails, but diamond_block succeeds.

granite_block, diorite_block, and andesite_block all fail, though.

I tried stone:2 (and other variations with the : replaced or removed) as well, based on this list, and that failed.

It looks like this might not be a bug, and might just be me making false assumptions about naming. But I'll leave it open just in case.

I just realized you're probably getting an e-mail message per comment: I'm sorry I should have thought of that earlier!

Tested several materials. Here's a list. Everything indented more failed, everything else not indented worked:

diamond_block
  diamond
dirt
glass
grass
cobblestone
stone
  andesite
  diorite
  granite
  andesite_block
  diorite_block
  granite_block
water
bedrock
air
lava
sand
gravel
gold_ore
iron_ore
coal_ore
sponge

  podzol
  planks
  red_sand

  oak_wood
  oak
  birch_wood
  birch

sandstone
  smooth_sandstone
  chiseled_sandstone

  bed
  noteblock

  wool
    white_wool
    whitewool


gold_block
iron_block

It's looking like this should be closed...

enebo commented

I see two issues:

  1. it is tough to know what to type so it is a guessing game: like I think diamond is only diamond_ore and diamond_block.
  2. Minecraft 1.8 changed something internally for blocks. Purugin asks Material.java for block types so :stone works fine. However it looks like in the new world there all stone blocks are stone + some field to say what kind of stone they are. So, I think I need to change something which will allow all valid block types to be specified.

This issue should get left open.

I plan to gradually build up a more complete list of usable material names, and put them into a command "materials", so I can either see a complete list at the console or see everything that matches a pattern.

If this list would be useful I can share it (when it's bigger than what I already posted), if you haven't already fixed this by the time I get to that.

As a slightly tangential issue, this might be useful to have available within Purugin, so that (e.g.) brick = Purugin::Material.new('diamond') throws an error such as 'Material name exception: I don't understand "diamond"; do you mean "diamond_block", or maybe "diamond_ore"?'

enebo commented

I think a list would be helpful sure.

I like your idea to suggest as well since the knowing what to spell problem is pretty easy to trip over. When I made the command language for generating more complicated plugins I also created a simple validator mechanism. Assuming we had the heuristics for suggesting good names then it can just be another builtin type validator commands can use when it requires block type names.

assuming I'm understanding you correctly, here are a few possible heuristic rules that might be worth considering:

  • a partial match could be used in place of the full name in cases where there's only one match
    ("diamond" if "diamond_ore" didn't exist, only "diamond_block")
  • an error with suggestions could be returned if there are multiple matches
    ("diamond" -> _ore or _block?)
  • "*_block" could be taken as the default, and therefore not required
    (so "diamond" would be taken as "diamond_block", but you'd need the "_ore" to get "diamond_ore")
  • if we wanted to get more complicated, in cases where the entered text turned into a regex doesn't match anything, then it could be broken up into an array of parts, like entered_text.split("_") and each part could be used as a regex, so "dimond_block" (missing 'a') would still return everything with "_block" as a suggestion.
  • there's probably some Ruby equivalent of aspell (or whatever) that could be used to suggest possibilities based on the parts, but maybe that's just too much bloat or complexity... (https://github.com/nithinbekal/spellingbee might work, if this seems worthwhile...)
  • a list of aliases might actually be the simplest approach, which could both provide more intuitive names than the Minecraft (or Spigot/Bukkit) API provides, and handle common misspellings
enebo commented

For abbreviating names I think we can just add aliases to the long names and I agree *_block can omit block as it is not descriptive and probably what people would naturally think of as the name.

As far as the suggestion mechanism on typos I do not care all that much if we include a gem or not. I have been trying to not have many/any deps but I don't want to write something which figures out closest match. With that said if you are interested in making some code for this then that would be great :)

Otherwise I think your other comments are pretty dependent on whether we use a library or not.

I'd love to submit a PR, but I'm hesitant to commit to anything since time is limited and it takes time to dig into the code and get oriented...

but, that said, since one of my goals with this is to get my son to learn Ruby, any time I spend on this sort of qualifies as family time ;)

(since I know you're open to PRs I'll be less hesitant to jump in and figure out how things work—just don't hold your breath for anything quickly)

enebo commented

yeah I would love to see PR(s). Also you have somewhat prompted me to get this back into proper shape again since I think it is a fun way to make plugins. Just the ability to edit the plugin in-place and have it auto-reload is great (and better than /reload).

Yes, I like that too. It sure beats restarting Minecraft! (Although
there are times when I have to do that because occasionally it doesn't seem
to autoreload properly... I can file another issue the next time I have
real data to post... I would guess it's because I've made a bigger change
than it is prepared for, like changing the plugin class name or
something...)

On Thu, Jan 21, 2016 at 4:23 PM, Thomas E Enebo notifications@github.com
wrote:

yeah I would love to see PR(s). Also you have somewhat prompted me to get
this back into proper shape again since I think it is a fun way to make
plugins. Just the ability to edit the plugin in-place and have it
auto-reload is great (and better than /reload).


Reply to this email directly or view it on GitHub
#58 (comment).

Brandon Zylstra
brandon.zylstra@gmail.com

enebo commented

@brandondrew My scrubbing logic is pretty basic too....So I would not be surprised if cases are not covered (it has been a long time since I wrote that...I don't really even remember many details).