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

[v0.1 - Beta] disknet

Started by KingofGamesYami, 04 August 2014 - 08:21 PM
KingofGamesYami #1
Posted 04 August 2014 - 10:21 PM
http://pastebin.com/bYc0XzLg

This program was inspired by someone requesting a "disk inter-world chat" program, and thus I've created a rednet-like api that uses disks. It is still in beta, and I am mostly posting this so people can find the bugs and give me ideas. One thing I want to figure out is, how could I keep the disk from being filled up? Is this even an issue? Other than that, ease of use comes to mind.

documentation:

- disknet.open( side, file ) –#returns an ID relating to the file
- disknet.receive( [file, [timeout, [ side ] ] ] ) –#returns the sent data
- disknet.isOpen( side ) –#returns boolean
- disknet.send( message, side, ID ) –#sends message
- disknet.broadcast( message ) –#calls send on every open file & side

Any questions will be answered comprehensively if possible. Be aware I have not extensively tested this, since I need to actually open minecraft to do so.
Edited on 04 August 2014 - 08:21 PM
Dragon53535 #2
Posted 06 August 2014 - 06:44 AM
Little newbie question, how do i install it correctly? Got it working, gimme a sec.

The program will not run as it doesn't realize that i've opened the disknet side correctly when i disknet.send() and using disknet.isOpen() returns true.

I fixed that by removing lines 34 and 35, and got it to write into a file IF there's a table in it already, which means you need to make it have a first time input. Currently though the receive is not working correctly as i can see that my messages are being saved and reviewing the code i guess maybe it's not actually creating a disknet event?

Actually i don't think that the file transfer between 2 floppies works. (i got it to work if i used creative mode middle click to copy the floppy, however just grabbing 2 floppies and labeling them the same doesnt't work.)
Edited on 06 August 2014 - 05:29 AM
KingofGamesYami #3
Posted 06 August 2014 - 11:03 PM
It should. Floppies named identically should be exactly the same.

Topic of disknet send, here's how I think it should work:

local id = disknet.open( "top", "chat" )
disknet.send( "Hello", "top", id ) --#note you NEED both "top" and id

To recieve:

local id = disknet.open( "top", "chat" )
local event, side, file, message = disknet.receive()

Test this out and see if it still works. As with rednet, the receiver must be open FIRST.

Edit: I think I found the bug, part of the code had differently named variables by accident. Updated pastebin

Here's the bit that makes the events:
Spoiler

local function checkFile()
		while true do
				for side, files in pairs( sides ) do
						for _, fileName in ipairs( files ) do
								local filePath = fs.combine( disk.getMountPath( side ), fileName )
								if fs.getFreeSpace( disk.getMountPath( side ) ) < 1000 then
										local file = fs.open( filePath, "w" )
										file.write( textutils.serialize( {} ) )
										file.close()
								end
								if fs.exists( filePath ) then
										local file = fs.open( filePath, "r" )
										local data = textutils.unserialize( file.readAll() )
										file.close()
										local toSend = {}
										for k, v in ipairs( data ) do
												if oldData[ k ] ~= v then
														toSend[ #toSend + 1 ] = v
												end
										end
										if #toSend > 0 then
												os.queueEvent( "disknet_message", side, fileName, textutils.serialize( toSend ) )
												oldFile[ side ] = data
										end
								end
						end
				end
				local id = os.startTimer( 0.1 )
				while true do
						local event, tid = os.pullEvent( "timer" )
						if id == tid then
								break
						end
				end
		end
end
-snip-


local cocheck = coroutine.create( checkFile )

function os.pullEventRaw( sFilter )
		while true do
				local event = { coroutine.yield() }
				if coroutine.status( cocheck ) == "suspended" then
						coroutine.resume( cocheck, unpack( event ) )
				end
				if event[ 1 ] == sFilter or not sFilter then
						return unpack( event )
				end
		end
end
Edited on 07 August 2014 - 04:25 AM
Dragon53535 #4
Posted 07 August 2014 - 11:20 PM
It still does not like making the file the first time. My fault there again, it doesn't like the file existing but nothing in it :P/> HOWEVER the disknet_message doesn't get new messages and your syntax is off, where you put message on the disknet.receive is getting the label on the computer.
Edited on 08 August 2014 - 01:25 AM
KingofGamesYami #5
Posted 08 August 2014 - 04:23 AM
It still does not like making the file the first time. My fault there again, it doesn't like the file existing but nothing in it :P/> HOWEVER the disknet_message doesn't get new messages and your syntax is off, where you put message on the disknet.receive is getting the label on the computer.
I've updated the pastebin since writing that post, you are correct. Also, testing myself on CC 1.63 it appears named floppies do not have the same files. Oh well…
LDDestroier #6
Posted 18 September 2014 - 12:43 AM
Do you think that you could make routers, which are seperate computers that have disk drives that take in rednet information, send it through disknet, then broadcast it back to rednet?
A computer could use a rednet chatroom, which would send the chatting over rednet to the router, then, over disknet, to another router, then to the computer.
Then the same thing the other way around.

Basically, worldwide rednet.

It would be better because you wouldn't have to rewrite programs to use disknet, and 1 router would work with many computers at once. Even pocket computers could use routers!
Oh, and the computers won't need a special client either, because it's:
[computer] -rednet–> [router] -disknet–> [router] -rednet–> [computer]

Work on that please. Like, now.
KingofGamesYami #7
Posted 18 September 2014 - 03:27 AM
This does not work. I mistakenly thought it would, and after testing realized it would not… Also there is a function called 'redRepeat', which is my attempt to do what you just said.
LDDestroier #8
Posted 18 September 2014 - 03:10 PM
This does not work. I mistakenly thought it would, and after testing realized it would not… Also there is a function called 'redRepeat', which is my attempt to do what you just said.

I had tested it too with the 1.7.10 beta, and I thought it worked. I had two duplicate floppies with nothing on them, put a file on one of them, then checked the other one, which then had that file with its contents. Please try it assuming disks do that.
KingofGamesYami #9
Posted 18 September 2014 - 03:16 PM
This does not work. I mistakenly thought it would, and after testing realized it would not… Also there is a function called 'redRepeat', which is my attempt to do what you just said.

I had tested it too with the 1.7.10 beta, and I thought it worked. I had two duplicate floppies with nothing on them, put a file on one of them, then checked the other one, which then had that file with its contents. Please try it assuming disks do that.
Yes, it works if you have litterally duplicated floppies, however this was made to work with named floppies, since how would you get identical floppies without cheating?
LDDestroier #10
Posted 18 September 2014 - 04:20 PM
This does not work. I mistakenly thought it would, and after testing realized it would not… Also there is a function called 'redRepeat', which is my attempt to do what you just said.

I had tested it too with the 1.7.10 beta, and I thought it worked. I had two duplicate floppies with nothing on them, put a file on one of them, then checked the other one, which then had that file with its contents. Please try it assuming disks do that.
Yes, it works if you have litterally duplicated floppies, however this was made to work with named floppies, since how would you get identical floppies without cheating?

They could be distributed in a server by admins. If someone is abusing the disknet, his disk is taken.
Edited on 18 September 2014 - 02:20 PM
LDDestroier #11
Posted 18 September 2014 - 08:36 PM
Could you better explain the syntax and functions of the disknet api? I need some example programs and explanations as to what goes on.
KingofGamesYami #12
Posted 18 September 2014 - 08:57 PM
- disknet.open( side, file ) –#returns an ID relating to the file
- disknet.receive( [file, [timeout, [ side ] ] ] ) –#returns the sent data
- disknet.isOpen( side ) –#returns boolean
- disknet.send( message, side, ID ) –#sends message
- disknet.broadcast( message ) –#calls send on every open file &amp; side


os.loadAPI( "disknet" )
local id = disknet.open( "right", "chat" )
disknet.send( "hello", "right", id )
local event, side, file, message = disknet.receive()
print( "recieved " .. message .. " on side " .. side .. " in file " .. file "!" )
LDDestroier #13
Posted 18 September 2014 - 09:01 PM
- disknet.open( side, file ) –#returns an ID relating to the file
- disknet.receive( [file, [timeout, [ side ] ] ] ) –#returns the sent data
- disknet.isOpen( side ) –#returns boolean
- disknet.send( message, side, ID ) –#sends message
- disknet.broadcast( message ) –#calls send on every open file &amp; side


os.loadAPI( "disknet" )
local id = disknet.open( "right", "chat" )
disknet.send( "hello", "right", id )
local event, side, file, message = disknet.receive()
print( "recieved " .. message .. " on side " .. side .. " in file " .. file "!" )
I'd like something more detailed than that. What does opening an ID do? Does it put data on the disk that the computer with that ID only can read? Do I use disknet.receive just like rednet.receive? What do I do exactly to load the api (put pastebin file on it with the name disknet then do command?)? Examples?
KingofGamesYami #14
Posted 19 September 2014 - 12:35 AM
You do not "open an id." You open a file on a side. "id" is simply a variable that holds a key to a table within the api, that contains the settings for that id.

disknet.receive is designed to work exactly like rednet.receive, except the outputs are modified (as you can see with my variables)

Load the api just like every other api…


>pastebin get bYc0XzLg disknet

os.loadAPI( "disknet" )

Edit: if you need more information, just look at the code… it's really not very complicated.
Edited on 18 September 2014 - 10:35 PM
LDDestroier #15
Posted 23 September 2014 - 08:06 PM
Well I don't know how to program well, if at all. Could you try just making a router program? It takes rednet info and broadcasts it on disknet, and takes disknet data (if it wasn't the message you broadcasted) and broadcasts it on rednet. Same with just to ids. Seems simple enough, but I suck at LUA, so please do that and I will put it on a server and cite you a lot.
LDDestroier #16
Posted 23 September 2014 - 10:19 PM
I tried disknet.send with the API loaded, but it told me that it had an invalid id. Here's what I put:


diskcast:2: Invalid disknet id

Diskcast is the thing I did to test sending data to a receiving disknet thing, that has the code:


disknet.open("right", "chat")
while true do
id, a = disknet.receive()
write(a)
end

All the receiver does is unlabel the floppy disk (back to "Floppy Disk") and do nothing else.

I need help with both of these. If I knew what the id was or what the event should be, then I might be able to fix it myself.
KingofGamesYami #17
Posted 23 September 2014 - 11:40 PM

function receive( pFilter, nTimeout, _side, _sender )
        local id
        if nTimeout and type( nTimeout ) ~= "number" then
                error( "Expected string, number[, string], got " .. type( pFilter ) .. ", " .. type( nTimeout ) .. "," .. type( _side ), 2 )
        elseif pFilter and type( pFilter ) ~= "string" then
                error( "Expected string, number[, string], got " .. type( pFilter ) .. ", " .. type( nTimeout ) .. "," .. type( _side ), 2 )
        elseif _side and type( _side ) ~= "string" then
                error( "Expected string, number[, string], got " .. type( pFilter ) .. ", " .. type( nTimeout ) .. "," .. type( _side ), 2 )
        end
        if nTimeout then
                id = os.startTimer( nTimeout )
        end
        while true do
                local event = { os.pullEvent() }
                if event[ 1 ] == "disknet_message" then
                        if event[ 2 ] == _side or not _side then
                                if event[ 3 ] == pFilter or not pFilter then
                                        return unpack( event )
                                end
                        end
                elseif event[ 1 ] == "timer" and event[ 2 ] == id then
                        return nil
                end
        end
end
LDDestroier #18
Posted 26 September 2014 - 09:35 PM

function receive( pFilter, nTimeout, _side, _sender )
		local id
		if nTimeout and type( nTimeout ) ~= "number" then
				error( "Expected string, number[, string], got " .. type( pFilter ) .. ", " .. type( nTimeout ) .. "," .. type( _side ), 2 )
		elseif pFilter and type( pFilter ) ~= "string" then
				error( "Expected string, number[, string], got " .. type( pFilter ) .. ", " .. type( nTimeout ) .. "," .. type( _side ), 2 )
		elseif _side and type( _side ) ~= "string" then
				error( "Expected string, number[, string], got " .. type( pFilter ) .. ", " .. type( nTimeout ) .. "," .. type( _side ), 2 )
		end
		if nTimeout then
				id = os.startTimer( nTimeout )
		end
		while true do
				local event = { os.pullEvent() }
				if event[ 1 ] == "disknet_message" then
						if event[ 2 ] == _side or not _side then
								if event[ 3 ] == pFilter or not pFilter then
										return unpack( event )
								end
						end
				elseif event[ 1 ] == "timer" and event[ 2 ] == id then
						return nil
				end
		end
end

What is the 'sender' and 'pFilter' things when setting the function, and their syntax? I'm lost when I look at the code.
Also, the thing I do see is that there is a 'while true do' loop in receive(). Does that mean that it the function will go on forever, or am I not looking deep enough and it ends when the timeout ends?
Edited on 26 September 2014 - 07:37 PM
KingofGamesYami #19
Posted 26 September 2014 - 10:06 PM
What is the 'sender' and 'pFilter' things when setting the function, and their syntax? I'm lost when I look at the code.
Also, the thing I do see is that there is a 'while true do' loop in receive(). Does that mean that it the function will go on forever, or am I not looking deep enough and it ends when the timeout ends?
The function would go on forever, except I have two cases in which it returns. 1) If the timer runs out or 2) when it receives a message. In the case of the former, it will return nil.

It looks like _sender was going to added and never was. It does nothing in that section of code.

pFilter is basically just that, a filter… It is similar to the rednet protocol.
Edited on 26 September 2014 - 08:07 PM
LDDestroier #20
Posted 29 September 2014 - 09:02 PM
What is the 'sender' and 'pFilter' things when setting the function, and their syntax? I'm lost when I look at the code.
Also, the thing I do see is that there is a 'while true do' loop in receive(). Does that mean that it the function will go on forever, or am I not looking deep enough and it ends when the timeout ends?
The function would go on forever, except I have two cases in which it returns. 1) If the timer runs out or 2) when it receives a message. In the case of the former, it will return nil.

It looks like _sender was going to added and never was. It does nothing in that section of code.

pFilter is basically just that, a filter… It is similar to the rednet protocol.

So can I simply not put the pFilter thing if I want it to see everything? And simply ignore sender?
KingofGamesYami #21
Posted 29 September 2014 - 09:23 PM
-snip-
So can I simply not put the pFilter thing if I want it to see everything? And simply ignore sender?

Yep. Sender is irrelevant.
LDDestroier #22
Posted 30 September 2014 - 05:22 PM
I tried making the routing program, but it didn't work. Didn't error either, but I need it debugged. Could you give it a go?
http://pastebin.com/dv6LDhVa

I promise not to remove it.
KingofGamesYami #23
Posted 30 September 2014 - 06:46 PM
I tried making the routing program, but it didn't work. Didn't error either, but I need it debugged. Could you give it a go?
http://pastebin.com/dv6LDhVa

I promise not to remove it.

as far as I can tell, the only problem is line 189:

        disknet.broadcast(a)

Since you have not loaded the api, just pasted the code in, shouldn't it be this?

       broadcast(a)
LDDestroier #24
Posted 30 September 2014 - 09:04 PM
I tried making the routing program, but it didn't work. Didn't error either, but I need it debugged. Could you give it a go?
http://pastebin.com/dv6LDhVa

I promise not to remove it.

as far as I can tell, the only problem is line 189:

		disknet.broadcast(a)

Since you have not loaded the api, just pasted the code in, shouldn't it be this?

	   broadcast(a)

I fixed that, but it still doesn't work right. I don't know if it's not broadcasting or not receiving. Could you please please get it working? The program goes on a computer with a disk drive and a wireless modem. I am completely lost.
Dragon53535 #25
Posted 30 September 2014 - 09:18 PM
Are you sending a rednet message to the computer running the program? Also whenever it stops, just press ctrl+t and it should give a line number where you stopped it.
LDDestroier #26
Posted 01 October 2014 - 11:25 PM
Are you sending a rednet message to the computer running the program? Also whenever it stops, just press ctrl+t and it should give a line number where you stopped it.

The program should take in rednet information and broadcast it on disknet, while at the same time broadcasting received disknet data on rednet.

This is a schematic (sort of) of how it should be connected. Note: where it says client, there can be multiple computers.

(By the way, the picture was made using a cheap linux paint clone. I've yet to find something as simple as mspaint.)
Edited on 01 October 2014 - 09:26 PM
Dragon53535 #27
Posted 01 October 2014 - 11:43 PM
I understand the purpose you are using it for, however it might stop whenever it's trying to rednet.receive() if nothing is being sent to it.
KingofGamesYami #28
Posted 02 October 2014 - 12:02 AM

while true do
  local event = { os.pullEvent() }
  if event[ 1 ] == "disknet_message" then
    --#send on rednet
  elseif event[ 1 ] == "rednet_message" then
    --#send on disknet
  end
end
LDDestroier #29
Posted 02 October 2014 - 12:52 AM

while true do
  local event = { os.pullEvent() }
  if event[ 1 ] == "disknet_message" then
	--#send on rednet
  elseif event[ 1 ] == "rednet_message" then
	--#send on disknet
  end
end

Will this go on if there isn't a rednet/disknet message? Because I'm using my laptop, and it lags with Lubuntu, so I can't run ComputerCraft.
Dragon53535 #30
Posted 02 October 2014 - 01:01 AM
No it will wait for some kind of event, and if that event's not one of those then it will start from the top
LDDestroier #31
Posted 02 October 2014 - 01:50 AM
No it will wait for some kind of event, and if that event's not one of those then it will start from the top

So if it gets any rednet message or disknet message, then it executes the right code?
Dragon53535 #32
Posted 02 October 2014 - 02:09 AM
it should, however the code Yami had when i was testing was flawed and it kept raising a disknet event
LDDestroier #33
Posted 02 October 2014 - 02:58 PM
it should, however the code Yami had when i was testing was flawed and it kept raising a disknet event

So should http://pastebin.com/dv6LDhVa work as intended? Because this could be an invaluable tool for huge multiverse city-based tekkit servers.
Dragon53535 #34
Posted 02 October 2014 - 11:06 PM
You have too many ends at the end of your program, you indented improperly, just delete one.
Line 141, you're using disknet.broadcast, since you're not loading the disknet api that should just be broadcast Same for 192.
When calling a broadcast from disknet when you receive a redstone message, i would assume you would want to send the message from the client, the way it's setup is that the client has to send 2 messages.
The same with rednet.send
LDDestroier #35
Posted 03 October 2014 - 03:35 PM
You have too many ends at the end of your program, you indented improperly, just delete one.
Line 141, you're using disknet.broadcast, since you're not loading the disknet api that should just be broadcast Same for 192.
When calling a broadcast from disknet when you receive a redstone message, i would assume you would want to send the message from the client, the way it's setup is that the client has to send 2 messages.
The same with rednet.send

Fixed. Does it work now? I can't test it right now.
LDDestroier #36
Posted 03 October 2014 - 08:06 PM
My pastebin has been updated, and it looks good. There's just one fatal problem.

I noticed that the code for your api looks for an event called "disknet_message". The router program recognizes the event "rednet_message" okay, but it doesn't see the event "disknet_message".

How does that get invoked? Do I have to add some code to my pastebin? If I do, please give me it. This actually might work.
KingofGamesYami #37
Posted 03 October 2014 - 08:30 PM
No, it should have everything.
LDDestroier #38
Posted 03 October 2014 - 08:54 PM
Here are the problems that I got right now:

-It appears to accept a rednet input once, but another one crashes it with the error: 'expected string, got number'.
-It either doesn't broadcast the disknet at all, or can't receive disknet.


Please revise it. I need this to work, and I am not skilled enough to pull this off.
Dragon53535 #39
Posted 04 October 2014 - 01:34 AM
Your code is flawed (If you are using the same pastebin) You should change inside your os.pullEvent() these

print("rednet: " .. rednet.receive())
broadcast(rednet.receive())

print("disknet: " .. receive())
rednet.broadcast(receive())
To these

print("rednet: ".. event[3])
broadcast(event[3])

print("disknet: " .. event[5])
rednet.broadcast(event[5])
LDDestroier #40
Posted 07 October 2014 - 05:17 PM
Should I just modify redrepeat() to print what text it gets and simply use that instead of what I added? Because if that works, then that would be great, and I would be annoyed because I tried for a while to get it to route data another way.

Should I just modify redrepeat() to print what text it gets and simply use that instead of what I added? Because if that works, then that would be great, and I would be annoyed because I tried for a while to get it to route data another way.

Even better, disknet could also use an encryption algorithm. It would use the public/private key thing, where two huge prime numbers are generated, then multiplied together as your public key.

That, or simply use a password to encrypt disknet data.
LDDestroier #41
Posted 07 October 2014 - 05:31 PM
I really want to use disknet to use a private chatroom to communicate with other people in LuaLand. I really like the server, and I want to use rednet programs (tarnchat, tron, file transfer, remote desktop) from 3000 meters away. I was going to make a wired cable over to a friend's house, but then I looked at his coordinates compared to mine. I don't have that much redstone or cobble.
LDDestroier #42
Posted 15 October 2014 - 03:11 PM
I screwed up the program again, and now it doesn't even ping anymore. It used to, which proves disknet works. Please, please just make it work! I can't do it at all. If only fs.open() and all the other fs things were simpler!
KingofGamesYami #43
Posted 15 October 2014 - 03:17 PM
I screwed up the program again, and now it doesn't even ping anymore. It used to, which proves disknet works. Please, please just make it work! I can't do it at all. If only fs.open() and all the other fs things were simpler!

fs is easy.


local handle = fs.open( "filename", "mode" ) --#mode is "r" if you want data, "w" if you want to change the data
handle.write( "string" ) --#writes a string to the file you previously opened
handle.writeLine( "string" ) --#adds a newline character to the end of write.
handle.close() --#saves the file and deletes the handle
handle.readAll() --#returns the data inside the file

I usually use the variable "file" for the handle.
LDDestroier #44
Posted 15 October 2014 - 03:21 PM
I screwed up the program again, and now it doesn't even ping anymore. It used to, which proves disknet works. Please, please just make it work! I can't do it at all. If only fs.open() and all the other fs things were simpler!

UPDATE: I might have fixed it, but I can't test it now.

I used the variable 'fyle' to remove the chance of a conflict.

Hey, mind testing the disknet router again? If it doesn't work, then I don't know what to do.

EDIT: Going through my comments in 2019 is causing me to cringe something awful!
I got a working version of disknet that works really nice, though. Tested in 1.12.2 CC:Tweaked.

https://github.com/LDDestroier/CC/blob/master/disknet.lua
Edited on 02 May 2019 - 04:36 AM