View Single Post
chucker
 
Join Date: May 2004
Location: near Bremen, Germany
Send a message via ICQ to chucker Send a message via AIM to chucker Send a message via MSN to chucker Send a message via Yahoo to chucker Send a message via Skype™ to chucker 
2006-04-16, 06:06

I was encouraged to post random bits of code, so I figured I'd whip up a small app and post it here.

Code:
#!/usr/bin/env ruby # Protocol docs: http://cho.cyan.com/chat/protocol1.html # # ToDo: # - implement ignore # - convert encodings (assumptions: CC uses Windows-1252; Ruby uses UTF-8) # - make interactive # - wrap UI around # require 'socket' Version = "1.0d5" DefaultHost = 'cho.cyan.com' DefaultPort = 1812 DebugPort = 1813 C2SNickname = 10 C2SQuit = 15 C2SPrivMsg = 20 C2SRoomMsg = 30 C2SWelcome = 40 C2SIgnore = 70 S2CNickErr = 10 S2CNickSet = 11 S2CPrivMsg = 21 S2CMessage = 31 S2CWhoList = 35 S2CWelcome = 40 S2CIgnore = 70 GroupUser = 0 GroupCyan = 1 GroupServer = 2 GroupGuest = 4 Timestamps = 1 RotateLines = 1 Nickname = "cccccccTest" class CCConnection < TCPSocket attr_accessor(:alreadyWelcomed, :connectAutomatically) attr_reader(:host, :port) def initialize(host=DefaultHost, port=DefaultPort) super(host, port) @alreadyWelcomed = 0 @connectAutomatically = 1 end def c2sCmd(cmd) self.send(cmd, 0) end def c2sNickname(nick) self.c2sCmd(C2SNickname.to_s + "|" + nick + "\n") end def c2sQuit() self.c2sCmd(C2SQuit.to_s + "\n") end def c2sPrivMsg(userclass, nickname, message) self.c2sCmd(C2SPrivMsg.to_s + "|" + userclass.to_s + nickname + "|^1" + message + "\n") # e.g. 21|0chucker|^1foo\n end def c2sRoomMsg(message) self.c2sCmd(C2SRoomMsg.to_s + "|^1" + message + "\n") end def c2sWelcome() self.c2sCmd(C2SWelcome.to_s + "|1\n") end def c2sIgnore() self.c2sCmd(C2SIgnore.to_s) # not implemented end end def printx(output) if Timestamps == 1 output = Time.now.strftime('%X ') + output + "\n" end print output end def errorx(output) if Timestamps == 1 output = Time.now.strftime('%X ERROR: ') + output + "\n" end print output end def s2cPrivMsg(line) if line.slice!(0) && (line[0].chr == GroupServer.to_s) && line.slice!(0) && line.include?("|^1") messageArray = line.split("|^1") messageSender = messageArray[0] messageContent = messageArray[1] printx "["+messageSender+"] "+messageContent end end def s2cWhoList(line) line.slice!(0) puts line whoHash = Hash[*line.split("|").map! {|x| x.split(",")}.flatten] # this isn't actually useful; # we need to store the Group as well, which is completely retarded but such is life. # Two-dimensional array, I suppose. puts whoHash.class puts whoHash.to_s puts whoHash["chucker"] # when RespWhoList.to_s # if bufferLines[0][0] == "|" # while bufferLines[0].length > 0 # bufferLines[0].slice!(0) # while bufferLines[0][0] != "," # tmp += bufferLines[0][0] # end # puts tmp # whoList[] # end # end end def s2cWelcome(line) printx(line) end def handleResponse(connection, line) case bufferCmd = line.slice!(0,2) when S2CPrivMsg.to_s s2cPrivMsg(line) when S2CWhoList.to_s if line.length > 1 if line[0].chr == "|" line.slice!(0) s2cWhoList(line) else errorx("Erroneous who list response! " + line) exit end else printx("Room is empty") end when S2CWelcome.to_s if line[0..1] == "|1" line.slice!(0,2) s2cWelcome(line) if connection.alreadyWelcomed == 0 connection.alreadyWelcomed = 1 if connection.connectAutomatically == 1 connection.c2sNickname(Nickname) sleep 3 connection.c2sPrivMsg(GroupUser, "chucker", "PM test") connection.c2sRoomMsg("Hi!") connection.c2sQuit() exit end end else errorx("Erroneous welcome response!") exit end else puts "cmd "+bufferCmd+"\n" end end connection = CCConnection.new() connection.c2sWelcome() i=1 while # this line / condition needs fixing, i.e. "while connection open" buffer = connection.recv(1024) # puts connection.alreadyWelcomed bufferLines = buffer.split(/\r\n/) puts bufferLines.length.to_s+" lines" puts bufferLines[0] if bufferLines.length > 1 while bufferLines.length > 1 if RotateLines == 1 bufferLines.reverse! end handleResponse(connection, bufferLines[0]) bufferLines.slice!(0) end else handleResponse(connection, bufferLines.to_s) end i+=1 end
There's various big problems with this code, notably:
  1. it's severely disorganized
  2. it's completely non-interactive
  3. outgoing commands are inside the CCConnection object (as desired); incoming ones are not.

As such, the anticipated improvements are:
  1. a more useful structure (I've been told by one person I sent this too that it is "actually pretty nicely written" and rather "clean", so I could be expecting too much)
  2. a means to make it interactive and eventually wrap a GUI around it
  3. a more logical grouping of commands.

Now, I don't know much about 1). As for 2): I know next to nothing about this. Sure, I can use primitive functions like "gets", but that's not exactly my idea. I experimented with ncurses about a year ago, in C, but didn't really like my results of that either. Ideally, I'd like this application to run on Windows, using a toolkit such as WxWidgets or FOX, but, again, I don't even know where to begin. Tutorials only make me blink; the extensions of WxRuby or FXRuby seem extremely non-Ruby-like to me.

Finally, 3): is it possible at all to put received commands in the class? After all, class methods are there to send a message to the class, not to receive one from it, so it's somewhat illogical. Am I missing something?

Any pointers whatsoever appreciated.
  quote