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

Multi-Computer Network

Started by Aus_Jad, 28 November 2015 - 05:13 AM
Aus_Jad #1
Posted 28 November 2015 - 06:13 AM
I am currently creating a Computercraft casino with blackjack and hookers on a server that requires a more advanced network and I've tried to do this multiple ways, sometimes they work perfectly fine in single player but not on a multiplayer server. (I'll just put here that im more looking at logic errors.)

The casino's layout is as follows basically works like this:




The "blackjack and other games" computers are being used at the same time and all communicate with the main computer at times. I've tried multiple different styled networks for this.

1) The main computer awaits a modem_message event from any of the computers.
2) Computer replies to computer that it got the modem_message as a confirmation that it can continue sending messages.
3) Based on the senderChannel of the first message the main computer does different things. such as creating a new user, updating credits etc.

If another computer sends a message at this time it doesn't receive a reply and just sends the same message a few seconds later.


example code for a user logging into there "casino account"

"Main PC"

while true do
	    event, modemSide, senderChannel1, replyChannel1, user = os.pullEvent("modem_message")  -- User = specific user, senderChannel =
	    if (event ~= "modem_message") then
		   os.reboot()
	    end
modem.transmit(replyChannel1, 0, "Processing Request")
if (senderChannel1 == 1) then
--code
end
if(senderChannel1 == 2) then
pass = samePC(replyChannel1)
			    if(fs.exists(user) == true) then
					    login = fs.open(user .."/pass", "r")
					    temp = login.readLine()
					    login.close()
					    if (temp == pass) then
							    modem.transmit(replyChannel1, 0, 1) -- Password correct
					    else
							    modem.transmit(replyChannel1, 0, 2) -- Password incorrect
					    end
			    else
					    modem.transmit(replyChannel1, 0, 0) -- user doesn't exist error
			    end
end
--etc
end

the samePC function checks that the replyChannel of the message containing the users password is the same as the PC that sent the username. It then returns that password. (This check is done using the replyChannel to check the PC is the same, it also checks that the senderChannel of this message is 0 which is just the channel I chose to send the main computer extra information.)


Users Computer (blackjack or w\e)

while true do
	    modem.transmit(2, reply, user)
	    local myTimer = os.startTimer(5)
	    local event, modemSide, SenderChannel, replyChannel, msg = os.pullEvent()
	    if event == "modem_message" then
			    os.cancelTimer(myTimer)
			    break
	    else
			    if event == "timer" then
			    end
	    end
end
while true do
	    modem.transmit(0, reply, pass)
	    local myTimer = os.startTimer(5)
	    event, modemSide, SenderChannel, replyChannel, successCheck = os.pullEvent()
	    if event == "modem_message" then
			    os.cancelTimer(myTimer)
			    break
	    else
			    if event == "timer" then
			    end
	    end
end

"modem.transmit(2, reply, user)" 2 being the senderChannel, reply being the ID of the current computer and user being the username for the casino account the user has put in.
senderChannel 2 is the main PCs code for a user log in.

Sometimes this code works sometimes it doesn't. I've had times when I've tried to make a new account and the username has been sent as both the username and password, but also times where it works perfectly fine. (I think in single player it works every time but on the multiplayer server it has this error.)

This is my current setup which apparently doesn't work. So I'm asking for ideas for different network setups. I was considering a ring network where the mainPC sends a message to each individual PC asking if it needs anything, no reply = it doesn't. But the casino has well over 30+ computers and I'm not sure how efficient that setup would be. (I.e. if using the rednet system is any better. I think the reason I chose to not use rednet was because the sender channels made it super easy to determine what the user's PC wanted from the main computer.)

alternatively I'm just bad at coding and my current setup works in theory but I've just implemented it extremely poorly so if anyone has a better idea of a way to do this I'd appreciate hearing it.
Bomb Bloke #2
Posted 28 November 2015 - 08:26 AM
Sometimes this code works sometimes it doesn't. I've had times when I've tried to make a new account and the username has been sent as both the username and password, but also times where it works perfectly fine. (I think in single player it works every time but on the multiplayer server it has this error.)

This code here:

while true do
            modem.transmit(2, reply, user)
            local myTimer = os.startTimer(5)
            local event, modemSide, SenderChannel, replyChannel, msg = os.pullEvent()
            if event == "modem_message" then
                            os.cancelTimer(myTimer)
                            break
            else
                            if event == "timer" then
                            end
            end
end

… is perfectly capable of sending the username more times than you'd want it to, and I'm betting your samePC() function doesn't much care whether passwords come in on channel 2 or 0.

For example, under CC 1.74, starting a script via the command prompt will usually result in a key_up event going into the event queue for that script to pull (when you let go of the enter key). Your loop will take that as an excuse to repeat, hence sending the username twice even if the main computer sent a reply as soon as it possibly could. Events could also come from other unexpected sources - you should be specific in that you only want to loop if the actual timer you created expires. For example:

local myTimer = os.startTimer(0)

while true do
	local event, modemSide, SenderChannel, replyChannel, msg = os.pullEvent()
	
	if event == "modem_message" then
		os.cancelTimer(myTimer)
		break
	elseif event == "timer" and modemSide == myTimer then
		modem.transmit(2, reply, user)
		myTimer = os.startTimer(5)
	end
end

You may find things easier if you create a table (containing eg your username, password, desired task, etc) and send the whole thing as your message in one go, rather than sending the bits of data one at a time across multiple messages.
Aus_Jad #3
Posted 28 November 2015 - 10:08 AM
Thanks for the response, the idea of it sending multiple times is that it may not "get through" to the main computer on the first attempt. I'll try your table idea because that seems a lot more efficient to what I currently have.
and I'm betting your samePC() function doesn't much care whether passwords come in on channel 2 or 0.

Actually:


local function samePC(replyChannel1)
	    repeat
			    event, modemSide, senderChannel, replyChannel, pass = os.pullEvent("modem_message")
	    until (replyChannel == replyChannel1 and senderChannel == 0)
	    return (pass)
end
Aus_Jad #4
Posted 28 November 2015 - 10:14 AM
Also I forgot to mention in my other post (due to restrictions instead of waiting im just going to make another one)

you should be specific in that you only want to loop if the actual timer you created expires

Thanks for that. That would work perfectly fine, the only thing Im not sure I agree with there is that you're making it run through the loop once before it's able to actually do anything.
Edited on 28 November 2015 - 09:14 AM