Hack-a-Day, Day 27: Minecraft Mod

Today I made a minecraft mod, using Fabric. Modding sure has changed a lot since I last tried it in Forge, maybe ten years ago! Java's changed a little too, even.

My mod adds a dirt slab, that's it. I didn't really have time to get past the basics, but I think the occasional hack that's just a learning experience is okay.

Code and mod download are both on github this time.

Tagged ,

Controlling a computercraft turtle remotely

Screen Shot 2015-10-18 at 7.16.59 PM
Screen Shot 2015-10-18 at 7.17.30 PM

  1. Install Redis: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-redis
  2. Install Webdis
  3. Start a minecraft server with computercraft. You will need to have the http API enabled, which is the default.
  4. Put down a turtle I recommend a turtle with a crafting square and a pickaxe. I also recommend giving it a label. If you’re not trying the turtle replication challenge, either disable fuel or get a fair bit of starting fuel. Write down the computer’s id.
  5. Put down a chunk loader, if you’re in a modpack that has them, or DON’T log out. Computers and turtles can’t operate unless the chunks are loaded. If you’re putting down a chunkloader, I surrounded them with bedrock for foolproofing.
  6. Open the turtle and download the following script, changing “redis.example.com” to your own redis instance: pastebin get 8FjggG9w startup
    After you have the script saved as ‘startup’, run it or reboot the computer, and it should start listening for instructions.

    redis = "http://redis.example.com" 
    queue = "sshbot" .. os.getComputerID()
    return_queue = queue .. "_return"
    print("Remote webdis queues on icyego: " .. queue .. " and " .. return_queue)
    print("Receiving remote commands.")
    
    function exec(str)
      print("Running: " .. str)
      f = fs.open("tmp", "w")
      f.write(str)
      f.close()
      p = loadfile("tmp")
     status, err = pcall(function () p = loadfile("tmp"); return p() end)
      if status then
        status, ret = pcall(function() return textutils.serialize(err) end)
        if status then
          result = ret
        else
          result = ""
        end
      else
        result = "Error: " .. err
      end
      print(result)
      return result
    end
    
    print("Now receiving remote commands.")
    while true do
      handle = http.get(redis .. "/BRPOP/" .. queue .. "/5.txt")
      if (handle and handle.getResponseCode() == 200) then 
        str = handle.readAll()
        handle.close()
        str = string.sub(str, string.len(queue) + 1)
        result = exec(str)
        if string.find(result, "Error: ") then
          result2 = exec("return " .. str)
          if string.find(result2, "Error: ") then a=0 else result=result2 end
        end
        http.post(redis, "LPUSH/" .. return_queue .. "/" .. result)
      end
    end
    
  7. On your local machine, save the following, again replacing “redis.example.com”:

    #!/bin/bash
    function send() {
      curl -s -X POST -d "LPUSH/sshbot${1}/${2}" "http://redis.example.com" >/dev/null
    
    }
    
    function get() {
      curl -s -X GET "http://redis.example.com/BRPOP/sshbot${1}_return/20.json" | jq .BRPOP[1]
    }
    
    if [ $# -ne 1 ]; then
      echo "Usage: rlwrap ./sshbot <COMPUTER_ID>"
      exit 1
    fi
    ID=$1
    
    while read LINE; do
      send ${ID} "$LINE"
      get ${ID}
    done
    
  8. Run: rlwrap ./sshbot , where is the turtle’s ID. You should be able to send commands to the computer now.

Tagged , ,

Running a forge server on headless linux

I’ve had a lot of trouble getting Minecraft Forge to run headless. They have a friendly installer option that I just can’t use in my situation, but one of the devs seems actively hostile around providing help to headless servers, so I didn’t bother asking forge for help. I thought I’d write up what I had to do to get things working. As a warning, it requires some local work; you can’t do everything headless with these directions.

I’m running Minecraft 1.6.4, with the latest version of forge for that, 9.11.1.965.

  1. Locally, download and start the minecraft client for the correct version at least once. Not sure if you’ll need to ‘play online’ or not. If you have the current installer, you need to make a new profile with the correct minecraft version and play that.
  2. Copy ~/.minecraft/libraries to the headless machine.
  3. Download forge (the installer version, not the universal) from http://files.minecraftforge.net/. The non-adly version is the little star for non-interactive use.
  4. Run

    java -jar forge-1.6.4-9.11.1.965-installer.jar --installServer
    
  5. Delete the installer, you don’t need it any more.

  6. Install any mods you want to the ‘mods’ directory, edit server.properties, etc. Normal server setup.
  7. To execute the server, run the file indicated in the installer. In my case, I run

    java -jar minecraftforge-universal-1.6.4-9.11.1.965-v164-pregradle.jar nogui
    

Alternatively, you can install the entire server locally and copy it over.

Tagged