Omnimaga
General Discussion => Gaming Discussion => Technology and Development => Minecraft Discussion => Topic started by: Keoni29 on January 01, 2013, 02:06:18 pm
-
Tekkit the famous modpack for minecraft contains a mod called computercraft. It allows you to place little computers running lua code in your minecraft world. You can even connect them to the Rednet. Rednet is an API which allows computers to communicate using a wireless modem. The first thing which came to my mind was: IRC.
I am learning lua and I don't really have an idea how exactely IRC should work on the server side. Does the server just pass trough any incoming messages?
This is what I've got so far:
(http://www.omnimaga.org/index.php?action=dlattach;topic=15463.0;attach=14421;image)
-
Sounds like a pretty cool idea. :) Could you do simple 2 player games like Pong, Tron, or perhaps even Tetris? That would be pretty neat too.
-
Yes that's possible and really simple too since it has setCursorPos(x, y) for text based gfx and the rednet api is easy to work with.
-
Are you actually trying to make it implement real IRC protocol? Have you read through an IRC RFC eg. http://tools.ietf.org/html/rfc2812 ?
-
Hmm perhaps it's easier to implement a chat with channels, nicknames and some commands rather than true irc. It's a pain to use the text editor in computercraft, so I don't want to have to write a lot of code.
Edit:
We got a working chat program. Both client and server.
Implemented commands so far:
/help
/join
/me
/msg
/nick
To do: some optimization and removing some glitches. (and of course more commands)
-
More commands implemented:
/quit
/who -- lists the online users
yet to implement /who #channel
-
My epic new server building!
-
Pretty cool stuff! ^^
-
The two lights that make up the cursor actually blink :)
-
Is there a way to export these lua programs to a text file (and load them from a text file)?
-
look under %appdata%/.minecraft/saves/*WORLD*/computer/*COMP #*/ all the files on the computer are stored there
-
Wow thanks. This is gonna make life so much easier :P
-
Here is the sourcecode for those who are interested:
IRCserver
SERVER = os.getComputerID()
nick = {}
channel = {}
--initialize names 1 to 128
for i=1,128 do
nick[i]="&new"
channel[i]="&new"
end
nick[SERVER] = "SERVER"
channel[SERVER] = "VIP LOUNGE"
function getUserId(str)
for i=1,128 do
if nick[i] == str then
return i
end
end
return nil
end
function listUsers(id)
p(id,"@ircOnline Users:")
for i=1,128 do
if nick[i]~="&new" and i~=SERVER then
p(id,"@irc -".. nick[i] .. " " .. channel[i])
end
end
end
function compare(str)
return string.find(message, str)
end
function newline()
mon.scroll(1)
mon.setCursorPos(1,20)
end
function post(str)
newline()
mon.write("<IRC>".. channel[senderId])
mon.setCursorPos(16,20)
mon.write(str)
chan = channel[senderId]
for i=1,128 do
if channel[i] == chan then
rednet.send(i,"@irc" .. str)
end
end
end
function addTime()
return "[" .. textutils.formatTime(os.time(),true) .. "]"
end
function postPrivate(receiver,str)
if getUserId(receiver) then
rednet.send(getUserId(receiver), "@irc".. addTime() .."<msg from ".. nick[senderId].. ">" .. str)
newline()
mon.write(addTime() .. "(msg " .. nick[senderId] .. " > " .. receiver .. ")" .. str)
else
rednet.send(senderId,"@ircUser " .. receiver .. " does not exist")
end
end
function p(i,str)
rednet.send(i,str)
end
function sendHelp(i)
p(i,"@irc--commands:------------")
p(i,"@irc /join channel -- joins the channel. example: /join #minecraft")
p(i,"@irc message -- sends plain text to the channel you're on")
p(i,"@irc /nick name -- changes your nickname. limited to 16 characters.")
--p(i,"@irc /msg receiver message -- sends a private message to 'receiver'")
p(i,"@irc /quit message -- quits IRC with a message")
end
rednet.open("left")
mon = peripheral.wrap("top")
mon.clear()
newline()
mon.write("IRC server software Alpha 1.0")
newline()
mon.write("Booting up server!")
rednet.announce()
repeat
senderId, message, distance = rednet.receive(1)
if senderId and string.len(message)>1 then
if nick[senderId]~="&new" or compare("/nick ")==1 then
if compare("/")==1 then
if compare("/join ")==1 and string.len(message)<=23 and string.len(message)>=1 and compare(" #")==6 then
channel[senderId]=string.sub(message, 7)
post(addTime() .. "*" .. nick[senderId] .. " has joined " .. channel[senderId])
elseif compare("/me ")==1 then
post(addTime() .. "*" .. nick[senderId] .. " " .. string.sub(message, 5) .. "*")
elseif compare("/nick ")==1 then
local oldnick= nick[senderId]
if string.sub(message,7,23)~="&new" then
nick[senderId] = string.sub(message, 7, 23)
if nick~=oldnick and oldnick~="&new" then
post(addTime() .. oldnick .. " changed his nickname to " .. nick[senderId])
end
end
elseif compare("/help")==1 then
sendHelp(senderId)
newline()
mon.write(addTime() .. nick[senderId] .. " requested help.")
elseif compare("/msg ")==1 then
msgStart = string.find(string.sub(message,6)," ")
if msgStart>1 then
postPrivate(string.sub(message,6,msgStart-1),string.sub(message,msgStart))
end
elseif compare("/quit ")==1 or compare("/quit") then
if nick[senderId]~="&new" then
post(addTime() .. "*".. nick[senderId] .. " has quit IRC (" .. string.sub(message,7) .. ")")
nick[senderId]="&new"
end
elseif compare("/who")==1 then
listUsers(userId)
end
else
post(addTime().. "<" .. nick[senderId] .. "> " .. message)
end
else
p(senderId,"@ircYou are not connected to IRC! type /join #irc")
end
end
until redstone.getInput("front")
rednet.close("left")
term.clear()
term.setCursorPos(1,1)
term.write("Closed Server!")
newline()
mon.write(addTime() .. "Closed Server!")
term.setCursorPos(1,2)
IRCclient
Note: Change SERVER = 29 to the ID of the server computer.
SERVER = 29
breakfree = false
function newline()
term.scroll(1)
term.setCursorPos(1,12)
end
function put(str)
newline()
term.write(str)
end
rednet.open("left")
rednet.announce()
function enterNick()
term.clear()
term.setCursorPos(1,1)
print("Enter nickname:")
username = read()
if string.len(username) and string.len(username)<=16 then
rednet.send(SERVER,"/nick " .. username)
rednet.send(SERVER,"/join #IRC")
return 0
else
return enterNick()
end
end
enterNick()
function1 = function()
while true do
local senderId, message, distance = rednet.receive(1)
if senderId and string.find(message,"@irc")==1 then
local x,y = term.getCursorPos()
put(string.sub(message,5))
term.setCursorPos(x,y)
end
if redstone.getInput("front") then
breakfree = true
return
end
end
end
function2 = function()
term.setCursorPos(1,14)
local message = read()
if string.find(message,"/quit")==1 then
breakfree=true
end
rednet.send(SERVER,message)
term.setCursorPos(1,14)
term.write(" ")
end
while not breakfree do
parallel.waitForAny(function1,function2)
end
rednet.send(SERVER, "/quit Client")
rednet.close("left")
I typed and debugged all of this using the ingame editor. It really sucks there are no linenumbers.
Edit: There is just one glitch: You can join with a name that is taken, so for instance when Keoni29 is on the IRC another guy can impersonate me by joining with the same nickname. It's probably quite easy to fix, but I leave that to someone else. I have had enough of the tekkit lua programming.