This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
jpiolho's profile picture

JPiolho's Programs [Utilities, APIs, Games, Turtle Scripts...] [Now with Steam and XFire API]

Started by jpiolho, 29 February 2012 - 10:17 PM
jpiolho #1
Posted 29 February 2012 - 11:17 PM
Posting the list of stuff I've developed and are worthy releasing.
Feel free to use and edit as long credits are retained.

Changelog
05-03-2012: Added 'XFire API' and 'Steam API' (APIs)
02-03-2012: Updated'Hill Eater' (Turtle) version 1.1, Added 'Setup Wizard' (Utilities)
01-03-2012: Added 'Download File' (Utilities) and 'Hill Eater' (Turtle)

—— Turtle ——
Maze Generator
SpoilerVersion: 1.1
Command Line: maze

Generates a maze any size you want. All you have to do after is define the start and exit.
The maze will be expanded front and to the right of the initial placement of the turtle.
The script needs to be running until the finish of the maze, it also does not support blockades at the moment. If the turtle is blocked for whatever reason, it will probably screw up the maze.

Word of advice, don't try huge mazes. A 128x128 maze took the turtle a whole day to build.


Download
Pastebin (Adf.ly) Pastebin (Direct)

Video
Shows the maze generation in action and explains a bit how it works too
Spoiler[media]http://www.youtube.com/watch?v=T0jWZUb9vPo[/media]

Changing maze size
SpoilerThe maze size is hardcoded on the script. Open the script and you'll see the following code:

local isDebug = false

local mazeWidth = 6
local mazeHeight = 6

Just change the mazeWidth and mazeHeight variables.
6x6 means its a 6x6 cells maze, but the actual maze size in blocks will be about twice that number.

Quickstart Tutorial
Spoiler1. On a relatively flat place, dig a 1 block hole and place the turtle in there.
2. Run the script
3. Watch the maze being constructed

Hill Eater
SpoilerVersion: 1.1
Command Line: hilleater


Eats all adjacent blocks infinitely starting from the place where the program was started.
Only eats blocks at the same or above the Y level where the program was started.

This allows a turtle to raze an entire hill, structure or tree, as long all blocks are connected to each other.
It can handle blocks that turtle can't dig or being unable to move. Rebooting is not supported (Restarting the program and continue work)

Changelog
02-03-2012 (1.1) - Now handles falling gravel and sand

Download
Pastebin (Adf.ly) Pastebin (Direct)

Video
Spoiler[media]http://www.youtube.com/watch?v=iWkZDiezrR0[/media]

—— APIs ——
How to install API's
SpoilerTheres multiple options to install and run APIs.

I own the server and I want to make it available for everyone
I play single-player and I want it available on all computers
Spoiler1. Download the API and save it in a file
2. Put the file into /mods/ComputerCraft/rom/apis/
3. You can now access the API via the the name you've put on the file.

I want to make it available only for a specific computer
Spoiler1. Download the API to your Computercraft computer in-game. You have multiple ways to do that (you can use my Download File script)
2. When you want your script to access the API use this line:
os.loadAPI("<the_api_filename>")
(replace <the_api_filename> with the name you gave to the API file in ComputerCraft.
3. You can now access it inside that specific script and on any other scripts in that computer that also include the os.loadAPI line.

Steam API
SpoilerVersion: 1.0
Requires HTTP API

This API allows you to gather information from Steam Community users, such as their current status (Online, Offline, In-game), list of games they own, hours they played, list of friends and even if they have golden potato :unsure:/>/>. The target user steam community profile must be public for this to work.

Download
Pastebin (Adf.ly) Pastebin (Direct)

Functions
Spoilersteam.userID(method,id)
This function returns the appropriate userID. There's 2 types of Steam Community profiles, the ones that have a fixed name, example: id/jpiolho, and then theres the one without fixed names, example: profile/76561198023194xxx.
- method is one of these: "id", "profile"
- id is the fixed name or the profile id
Spoiler
print(steam.userID("id","jpiolho")) -- id/jpiolho 

steam.getGamesList(userID)
Retrieve all the games the user owns and the play time for each one too.
- userID is the value returned by steam.userID or input manually "method/id"
Spoiler
-- Print the entire user games list
local games = steam.getGamesList(steam.userID("id","jpiolho"))
for game,hours in pairs(games) do
 print(game .. " || Played " .. hours .. "h")
end

steam.getStatus(userID)
Retrieve the user status. The status will return "Offline","Online" or the name of the game the user is currently playing.
- userID is the value returned by steam.userID or input manually "method/id"
Spoiler
-- Print the current user status
local status = steam.getStatus(steam.userID("id","jpiolho"))
if status == "Online" then
 print("User is online")
elseif status == "Offline" then
 print("User is offline")
else
 print("User is currently playing " .. status)
end

steam.getFriends(userID)
Retrieve all friends from a specific user. The table format is: userid = username
- userID is the value returned by steam.userID or input manually "method/id"
Spoiler
-- Print all friends from a specific user
local games = steam.getFriends(steam.userID("id","jpiolho"))
for friendID,friendName in pairs(games) do
 print(friendname .. " [ID: " .. friendID .. "]")
end

steam.isGoldenPotato(userID)
Returns whether the user has a golden potato or not
- userID is the value returned by steam.userID or input manually "method/id"
Spoiler
-- Print the entire user games list
if steam.isGoldenPotato(steam.userID("id","jpiolho")) then
 print("He has a golden potato!")
else
 print("Omg, he doesn't have one B)/>/>")
end

XFire API
SpoilerVersion: 1.0
Requires HTTP API

This API allows you to gather information from XFire user profiles, such as Gaming History, Online status, total gaming hours and the gaming rig.
I'll consider to expand this if people find this useful. However, retrieving individual game playing hours does not seem to be possible right now (at least with ComputerCraft).

Download
Pastebin (Adf.ly) Pastebin (Direct)

Functions
Spoilerxfire.getGamingHistory(username)
Returns the entire gaming history of the user. All the games the user played.
- username is the xfire username of the user
Spoiler
-- Print the entire gaming history of the user
local games = xfire.getGamingHistory("jpiolho")
for _,game in pairs(games) do
 print(game)
end

xfire.getGamingRig(username)
Returns all the info from the user gaming rig section.
- username is the xfire username of the user
Spoiler
-- Print the user entire gaming rig
local rig = xfire.getGamingRig("jpiolho")
for key,value in pairs(rig) do
 print(key .. ": " .. value)
end

xfire.getTotalPlayHours(username)
Returns the total number of hours the user played with XFire tracking.
- username is the xfire username of the user
Spoiler
-- Print the amount of hours the user played
print("JPiolho played " .. xfire.getTotalPlayHours("jpiolho") .. " hours of games")

xfire.getStatus(username)
Returns the user current online status.
- username is the xfire username of the user
Spoiler
if xfire.getStatus("jpiolho") == "Online" then
 print("The user is online!")
else
 print("The user is offline B)/>/>")
end

Craftnet
SpoilerVersion: 1.2

Craftnet is an API I've done for Computercraft 1.2 for transmitting stuff over redstone to other computers.
This was done as an alterative for rednet at the time which relied on bundled cables and the server I was playing at didn't have RedPower.

Download
Pastebin (Adf.ly) Pastebin (Direct)

More Info…
SpoilerRequires at least 2 redstone wires to communicate with other computer, but this is scalable, you can fill all the 6 sides with redstone for faster speeds.
You can also use two-way repeaters for long-distance communications, however, the speeds will be quite slow due to torches and repeaters delay.

You can connect multiple computers to the same wire network, however it's something I would avoid myself, the API has methods for handling this kind of connections, but you'll need to do some extra programming as it's very low-level stuff. You can however connect multiple pcs to each others by using less wires. For example, you can connect up to 3 pcs to a single one by using 2 wires for each.

Speeds:
The fastest speed for direct connection I could use is 0.06 per bit(s)
Using that as calculations and previous tests here's the table (give or take a few milliseconds):
* 2 wires - 2 bytes per second
* 3 wires - 4 bytes per second
* 4 wires - 5 bytes per second
* 5 wires - 8 bytes per second
* 6 wires - 8 bytes per second (= 5 wires)

With 2-way repeaters:
* 2 wires - 4.8 seconds per byte
* 3 wires - 2.4 seconds per byte
* 4 wires - 1.8 seconds per byte
* 5 wires - 1.2 seconds per byte
* 6 wires - 1.2 seconds per byte (= 5 wires)


Packets:
Craftnet uses a packet-style approach. This means the target computer must know what kind of data it is receiving.
The built-in methods allow you to send bytes (8 bits), shorts (16 bits), ints (32 bits), and strings (1 byte for size + 1 byte per character). If you really want super speed you also have a function which I called Weirdos for sending an arbitrary bit length number.

How it works
SpoilerAt first I tried with 1 wire only. I was able to send a byte without problems, but all the bytes after that one were corrupted, due to out of sync.
Then I came up with the idea to use 2 wires. One for the bit, another for the clock.
Every time the clock changes, the other computer reads the bit.

To achieve higher speeds with more wires, the multiple wires transmit multiple bits at the same clock. The reason why 6 wires speed is equal to 5 wires speed is because it needs 2 clock time, the same as with 5 wires (6 wires = 5 bits per clock, 5 wires = 4 bits per clock)

Functions
Spoilercraftnet.Open(datasides,clockside)
Opens a connection. Returns the connection ID.
- datasides is a table containing all the sides that are used for data sending. Order is very important, for example, if your #1 wire in the pc1 is "left" but it connects to the "right" of the pc2, then pc2 will have to open the #1 wire as "right".
- clockside is a string containing the side that is used for the clock.
Spoilerlocal conn = craftnet.Open({"back"},"left")

craftnet.Receive(connID)
Waits for an incoming signal.
- connID is the connection ID returned from craftnet.Open
Spoilercraftnet.Receive(conn)

craftnet.IsReceiving(connID)
Returns whether the connection is currently receiving a packet
- connID is the connection ID returned from craftnet.Open
Spoilerif craftnet.IsReceiving(conn) then print("BUSY") end

craftnet.IsSending(connID)
Returns whether the connection is currently sending a packet
- connID is the connection ID returned from craftnet.Open
Spoilerif craftnet.IsSending(conn) then print("BUSY") end

craftnet.IsBusy(connID)
Returns whether the connection is currently receiving or sending a packet
- connID is the connection ID returned from craftnet.Open
Spoilerif craftnet.IsBusy(conn) then print("BUSY") end

craftnet.GetSpeed(connID)
Returns the connection speed
- connID is the connection ID returned from craftnet.Open
Spoilerprint("Speed: " .. craftnet.Getspeed(conn) .. " ms")

craftnet.SetSpeed(connID,speed)
Sets the connection speed
- connID is the connection ID returned from craftnet.Open
- speed is the amount of seconds per each clock tick. 0.06 is recommended for direct connections.
Spoilercraftnet.SetSpeed(conn,0.06)

craftnet.BeginPacket(connID)
Initializes a packet. Either its sending or receiving. If it's sending, it will send the incoming signal.
- connID is the connection ID returned from craftnet.Open
Spoilercraftnet.BeginPacket(conn)
– Send or receive data here
craftnet.EndPacket(conn)

craftnet.EndPacket(connID[,sleep])
Ends a packet, making it ready for another one.
- connID is the connection ID returned from craftnet.Open
- sleep is a boolean telling whether it should wait a clock-time before continuing program. This is required if you're sending a packet after another.
Spoilercraftnet.BeginPacket(conn)
– Send data here
craftnet.EndPacket(conn)

craftnet.ReceiveByte(connID), craftnet.ReceiveInt16(connID), craftnet.ReceiveInt32(connID), craftnet.ReceiveString(connID)
Receives data from the packet. Should only be called between BeginPacket and EndPacket.
- connID is the connection ID returned from craftnet.Open
Spoilercraftnet.BeginPacket(conn)
print("> " .. craftnet.ReceiveString(conn))
craftnet.EndPacket(conn)

craftnet.ReceiveWeirdo(connID,size)
Receives data from the packet. But this allows you to specify the number of bits of the data. Should only be called between BeginPacket and EndPacket.
- connID is the connection ID returned from craftnet.Open
- size is the number of bits of the number you're expecting.
Spoilercraftnet.BeginPacket(conn)
print(craftnet.ReceiveWeirdo(conn,4)) – Receive a quick small number
craftnet.EndPacket(conn)

craftnet.SendByte(connID,num), craftnet.SendInt16(connID,num), craftnet.SendInt32(connID,num), craftnet.SendString(connID,text)
Sends data to the packet. Should only be called between BeginPacket and EndPacket.
Please notice that the SendString only supports strings up to 255 in length.
- connID is the connection ID returned from craftnet.Open
- num/text is the value to be sent.
Spoilercraftnet.BeginPacket(conn)
craftnet.SendString(conn,"Hello! How you doing?")
craftnet.EndPacket(conn)

craftnet.SendWeirdo(connID,num,size)
Sends data to the packet. But this allows you to specify the number of bits of the data. Should only be called between BeginPacket and EndPacket.
- connID is the connection ID returned from craftnet.Open
- num the data to be sent
- size is the number of bits of the number you're expecting.
Spoilercraftnet.BeginPacket(conn)
craftnet.SendWeirdo(conn,5,4) – Sends 5 in a 4-bit number
craftnet.EndPacket(conn)

craftnet.WaitForClock(connID)
This is more like an internal function but you might have use for it. Basically holds the program till the next clock tick.
- connID is the connection ID returned from craftnet.Open

Example
SpoilerConsider the following scenario:

2 computers connected with 3 wires. (2 for data, 1 for clock)

On Computer 1, we have the following program:
os.loadAPI("craftnet")

local conn = craftnet.Open({"left","right"},"back")
craftnet.SetSpeed(conn,0.06)

io.write("Message: ")
local msg = read()

craftnet.BeginPacket(conn)
craftnet.SendString(conn,msg)
craftnet.EndPacket(conn)

print("Message sent!")

On Computer 2, we have the following program:
os.loadAPI("craftnet")

local conn = craftnet.Open({"right","left"},"back")

craftnet.Receive(conn)

craftnet.BeginPacket(conn)
msg = craftnet.ReceiveString(conn)
craftnet.EndPacket(conn)

print(msg)

Now follow these steps:
1. On Computer 2, start the program.
2. On Computer 1, start the program
3. Input the message on computer 1.
4. Wait for the message on computer 2 to show up

Notes
Notice the order in craftnet.Open on both computers. On the 1 is left, but on the 2 is right first. Thats because as you can see on the image, computer 1 left wire is actually the right wire for computer 2. If the orders are wrong then the data will be corrupted.

—— Utilities ——
Upload File
SpoilerVersion: 1.0
Command Line: uploadfile <file>

Uploads a ComputerCraft file to TinyPaste.com using HTTP API.
If the file is too big, it will be split into multiple parts.
URL's will be returned where you can access.

By default, the limit I've put is 4KB per part.


Download
Pastebin (Adf.ly) Pastebin (Direct)

Options
SpoilerOptions are hardcoded in the script. Open the script and you'll see the following code:

local dataChunks = 4096 -- The amount of data each upload should have. If you put a big number then http api might not upload it
local pauseAfter = 10 -- After these number of parts are uploaded and theres more, a message will show up asking the user to press any key to continue

dataChunks is in bytes. The limit is not exact, this means it can be more, but will never be less than that number.

Quickstart Tutorial
Spoiler1. Run the script with the following command line: uploadfile <file>
2. Get the URL(s) and open in your browser

Download File
SpoilerVersion: 1.0
Command Line: downloadfile <provider>
 <target>

Downloads a file from internet using HTTP API.
You can specify a direct url, or a paste provider and the code.

[spoiler]downloadfile [url="http://www.google.com"]http://www.google.com[/url] myfile
downloadfile pastebin pdwaD9eZ myfile
[/spoiler]

List of supported providers:
* Ideone
* Pastebin
* Tinypaste
* Codepad
* Pastebay


[color=#ff8c00][size=5][b]Download[/b][/size][/color]
[url="http://adf.ly/5ttmw"]Pastebin (Adf.ly)[/url]  [url="http://pastebin.com/VmMTWZY2"]Pastebin (Direct)[/url]


Setup Wizard
SpoilerVersion: 1.0
Command Line: setupwizard <folder path=""> [options]

Automatically creates an installer for your programs. Best thing is, it stores all your files inside the installer script itself so no need for copying multiple files into a disk, just need the installer script.

All you have to do is specify the folder or root ("/") and it will quickly create a script named "setup". The setup will ask the user where to install and creates the files to the chosen folder.

Example:
Spoilersetupwizard myOS
setup OperatingSystems

Download
Pastebin (Adf.ly) Pastebin (Direct)
For this, it is recommended that you name the script "setupwizard", otherwise it might pack up the wizard along with your programs.

—— Games ——
Minesweeper
SpoilerVersion: 1.0
Command Line: minesweeper

A crude minesweeper game. This was actually my first script for ComputerCraft.
Has a weird bug that even after hours looking at it I couldn't solve, but don't worry about it B)/>/>

An interesting side note, if you put a node block on the right side, it will play it when you move in the menus.

Download
Pastebin (Adf.ly) Pastebin (Direct)

Images
Spoiler
Edited on 06 March 2012 - 01:15 PM
Chub1337 #2
Posted 01 March 2012 - 08:21 AM
This.. How.. Did you..? What..?

Teach me about the maze generator! I don't really get how it works.. :unsure:/>/>

And on a side note, if you would tell the bot which created the maze to go the the exit, would it do so that flawlessly?

-Chub1337
jpiolho #3
Posted 01 March 2012 - 09:04 AM
Wikipedia has a nice article explaining this and other maze generation algorithms. These algorithms don't define a start or exit point, what you can do is dig a block somewhere on the edge and call that start, and then on the opposite edge dig another block and call that the exit.
However, even if the turtle did that, there was no way to know the path back, because this algorithm uses a breadcrumb style navigation while building the maze. Creates a new area and drops a crumb, then when its coming back picks it up, effectively forgetting what's behind him.

Solving mazes is another article. I might pick it up and do a script to solve mazes.
Chub1337 #4
Posted 01 March 2012 - 02:50 PM
Hmm, I might make myself a maze solving turtlebot using the Trémaux's algorithm.. I've tried it on a 15x15 (so 30x30) maze myself (which was made by a turtlebot running your maze generator) and it gave me plenty of ideas.

Too bad I don't have enough time to make it yet.

Anyway, shall I post it here once I complete it?

-Chub1337
jpiolho #5
Posted 01 March 2012 - 06:21 PM
Not required, but I'll gladly put a link for it under the Maze Generation script.
jpiolho #6
Posted 05 March 2012 - 12:41 PM
Added XFire API and Steam API, enjoy.
xIGBClutchIx #7
Posted 10 March 2012 - 07:42 PM
Download File is not working
Error:
jpiolho #8
Posted 11 March 2012 - 07:20 AM
Most likely you or the server don't have HTTP API enabled.
Wolvan #9
Posted 11 March 2012 - 08:38 PM
Am I allowed to build a fetcher for my programs out of your downloader?
jpiolho #10
Posted 11 March 2012 - 09:07 PM
Sure, not a problem.
Ryusho #11
Posted 17 March 2012 - 02:17 AM
I had to type this program in very, very carefully, and I am getting an odd error, it tells me 129 called nil, well in my typed out version , I had to type it out because I was saving it on a floppy disk, on a SMP server, and well the line is
  1. math.randomseed(os.time())
for some reason, This line, it says "hilleater:129: attempt to call nil"

Any idea why? This is your HillEater program
monkeyloose #12
Posted 13 January 2013 - 10:07 PM
Um… help. I am able to install the program and run it in a specific computer, but when the program runs the turtle just spins in circles and breaks a 1 X 1 cross. But it does not move on to the rest of the maze, when i looked at the debug screen in game in gives the turtle move commands but the turtle does not move. What am i doing wrong?
Skullblade #13
Posted 14 January 2013 - 04:52 AM
don't bump 9 month old projects…just don't if you have a question pm the creator