Tiberian Sun WOL IRC Server

By sean on Jun 06, 2010

This is a Westwood Online server emulator for Command and Conquer: Tiberian Sun.

Simply open mIRC, load this snippet and type /twol
Once that's done, you'll need to /set %twol.ip
Finally, you'll need to open ports 4000 and 4005 via your network or modem; then you're all set.

;##
;# Tiberian Sun WOL IRC Server
;# by: Sean Wragg <seanwragg@gmail.com>
;##

alias twol {
  socklisten twols 4005
  socklisten twoll 4000
  hmake twol.games
  hmake twol.nicks
  var %i = 0
  while ( %i <= 9 ) { 
    hadd -m twol.lobbies $+($chr(35), Lob_18_, %i)
    inc %i
  }
}

alias -l e {
  var %w = @TWOL
  if ( !$window(%w) ) { window -e0k0nx %w }
  aline %w $1-
}

alias -l Sw {
  var %s = $+(twol.S-, $1)
  sockwrite -n %s $2-
}

on *:socklisten:twols:{
  var %s = $+(twol.S-, $ticks)
  sockaccept %s
  e Accepted client to %s 
}

on *:sockread:twol.S-*:{
  var %s = $sockname, %r
  var %id = $gettok(%s, 2, 45)
  sockread %r
  if ( !%r ) halt
  tokenize 32 %r
  if ( $1 == QUIT ) {
    Sw %id : 610 u 1
    Sw %id : 605 u : $+ %twol.ip 4000 '0:TWOL (development)' -8 36.1083 -115.0582
    Sw %id : 607
    sockclose %s
  }
}

alias -l Lw {
  var %s = $+(twol.L-, $1)
  sockwrite -n %s $2-
  e Sr: $1 <- $2-
}

on *:socklisten:twoll:{
  var %s = $+(twol.L-, $ticks)
  sockaccept %s
  e Accepted client to %s 
}

on *:sockread:twol.L-*:{
  var %s = $sockname, %r
  sockread %r
  e Lr: %id -> %r
  if ( !%r ) halt
  tokenize 32 %r
  ;# only two connections per ip (bot prevention)
  var %i = 1, %x = $sock(twol.L-*, 0), %c = 0
  while ( %i <= %x ) { 
    if ( $sock(twol.L-*, %i).ip == $sock(%s).ip ) { inc %c }
    inc %i
  }
  if ( %c > 2 ) { sockclose %s | halt }
  core.process %s %r 
}

alias core.process {
  var %s = $1, %id = $gettok(%s, 2, 45)
  if ( $2 == CVERS ) {
    ;# do nothing
  }
  else if ( $2 == PASS ) {
    ;# do nothing
  }
  else if ( $2 == NICK ) {
    if ( !$sock(%s).mark ) { 
      var %r = ^[0-9a-zA-Z]{3,9}$
      if ( $regex($3, %r) ) { sockmark %s $3 }
      else { Lw %id ERROR :closing link:(Password needed for that nickname.) | sockclose %s | halt }
    }
  }
  else if ( $2 == APGAR ) {
    ;# check pass creditentials
    var %p = $readini(apgar.ini, n, $sock(%s).mark, apgar) 
    if ( %p && %p != $3 ) { Lw %id ERROR :closing link:(Password needed for that nickname.) | sockclose %s | halt }
    else if ( !%p ) {
      writeini -n apgar.ini $sock(%s).mark apgar $3
      ;writeini -n apgar.ini $sock(%s).mark ip $sock(%s).ip
    }
    if ( $hget(twol.nicks, $sock(%s).mark) ) { clear.nick_instance $sock(%s).mark }
    if ( !$hget(twol.nicks, $sock(%s).mark) ) { hadd -m twol.nicks $sock(%s).mark $+(%id, $chr(58), $sock(%s).ip) }
  }
  else if ( $2 == SERIAL ) {
    ;# do nothing
  }
  else if ( $2 == USER ) {
    ;# do nothing
  }
  else if ( $2 == verchk ) {
    Lw %id : 375 u :- Welcome to the TWOL Development Server!
    Lw %id : 375 u :- $sock(twol.L-*, 0) people are online!
    Lw %id : 376 u
    Lw %id : 379 u :none none none 1 32512 NONREQ
  }
  else if ( $2 == SETOPT ) {
    ;#do nothing
  }
  else if ( $2 == SETCODEPAGE ) {
    Lw %id : 329 u $left($3, 5)
  }
  else if ( $2 == SETLOCALE ) {
    Lw %id : 310 u $3
  }
  else if ( $2 == LIST ) {
    if ( $4 == 18 ) {
      Lw %id : 321 u:
      if ( $3 == 0 ) {
        var %x = $hget(twol.lobbies, 0).item, %i = 1
        while ( %i <= %x ) { 
          Lw %id : 327 u $hget(twol.lobbies, %i).item $numtok($hget(twol.lobbies, $hget(twol.lobbies, %i).item), 32) 0 388
          inc %i
        }
      }
      else if ( $3 == 18 ) {
        var %x = $hget(twol.games, 0).item, %i = 1
        while ( %i <= %x ) {
          Lw %id : 326 u $hget(twol.games, %i).item $numtok($gettok($hget(twol.games, %i).data, 2, 47), 58) 0 18 $iif($gettok($gettok($hget(twol.games, %i).data, 1, 47), 5, 32), $gettok($gettok($hget(twol.games, %i).data, 1, 47), 5, 32), 0) 0 $gettok($gettok($hget(twol.games, %i).data, 1, 47), 6-, 32)
          inc %i
        }
      }
      Lw %id : 323 u:
    }
  }
  else if ( $2 == JOIN && $3 ) {
    ;# we can't join a channel if we're already in one
    if ( !$gettok($hget(twol.nicks, $sock(%s).mark), 3, 58) ) {
      ;# lobbies should be the only thing users are able to join and the pass should be zotclot9
      if ( $left($3, 5) == #Lob_ && $4 == zotclot9 ) {
        hadd twol.lobbies $3 $addtok( $hget(twol.lobbies, $3), $sock(%s).mark, 32 )
        ;# note where client is
        hadd twol.nicks $sock(%s).mark $addtok($hget(twol.nicks, $sock(%s).mark), $3, 58)
        Lw %id : $+ $+($sock(%s).mark,!u@h) JOIN :0,0 $3
        var %l = $hget(twol.lobbies, $3), %x = $numtok($hget(twol.lobbies, $3), 32), %i = 1, %rj
        while ( %i <= %x ) {
          var %ci = $readini(apgar.ini, n, $gettok(%l, %i, 32), clan)
          %rj = $+( $iif(%rj, $+(%rj, $chr(32)), $chr(58)), $gettok(%l, %i, 32), $chr(44), $iif(%ci, %ci, 0), $chr(44), 0 )
          inc %i
        }
        Lw %id : 353 u * $3 %rj
        Lw %id : 366 u $3 :
        update.lobby $sock(%s).mark JOIN $3
      }
    }
  }
  else if ( $2 == JOINGAME && $3 ) {
    ;# we can't join a channel if we're already in one
    if ( !$gettok($hget(twol.nicks, $sock(%s).mark), 3, 58) ) {
      ;# we also need to insure the channel exists and that we can only create a channel in the users nick
      if ( $hget(twol.games, $3) || $right($left($3, -7), -1) == $sock(%s).mark ) {
        ;# if hosting make new entry
        if ( $right($left($3, -7), -1) == $sock(%s).mark ) {
          hadd twol.games $3 1 $5 18 1 $iif($9 >= 1, $9, 0) $longip($gettok($hget(twol.nicks, $sock(%s).mark), 2, 58)) $+($iif($11, 384, 128), $chr(58)) $+($chr(47), $sock(%s).mark, $chr(47), $iif($11, $11))
        }
        ;# check if the channel if passworded
        else if ( $gettok($hget(twol.games, $3), 3, 47) && $5 ) { 
          if ( $5 == $gettok($hget(twol.games, $3), 3, 47) ) {
            ;# meh..also check if channel is full
            if ( $numtok($gettok($hget(twol.games, $3), 2, 47), 58) == $gettok($gettok($hget(twol.games, $3), 1, 47), 2, 32) ) { Lw %id : 471 u $3 | halt }
            ;# meh..also check if user is banned
            else if ( $gettok($hget(twol.games, $3), 3, 47) ) {
              var %l = $gettok($hget(twol.games, $3), 3, 47), %x = $numtok(%l, 58), %i = 1
              while ( %i <= %x ) {
                if ( $gettok(%l, %i, 58) == $sock(%s).mark ) { Lw %id : 474 u $3 | halt }
                inc %i
              }
            }
            hadd twol.games $3 $+($gettok($hget(twol.games, $3), 1, 47), $chr(47), $addtok( $gettok($hget(twol.games, $3), 2, 47), $sock(%s).mark, 58 ), $chr(47), $iif($gettok($hget(twol.games, $3), 3, 47), $gettok($hget(twol.games, $3), 3, 47))  )
          }
          else { Lw %id : 475 u $3 | halt }
        }
        ;# check if channel is full.
        else if ( $numtok($gettok($hget(twol.games, $3), 2, 47), 58) == $gettok($gettok($hget(twol.games, $3), 1, 47), 2, 32) ) { Lw %id : 471 u $3 | halt }
        ;# check if user is banned
        else if ( $gettok($hget(twol.games, $3), 3, 47) ) {
          var %l = $gettok($hget(twol.games, $3), 3, 47), %x = $numtok(%l, 58), %i = 1
          while ( %i <= %x ) {
            if ( $gettok(%l, %i, 58) == $sock(%s).mark ) { Lw %id : 474 u $3 | halt }
            inc %i
          }
        }
        ;# if everything is fine, add user to channel
        else { 
          hadd twol.games $3 $+($gettok($hget(twol.games, $3), 1, 47), $chr(47), $addtok( $gettok($hget(twol.games, $3), 2, 47), $sock(%s).mark, 58 ), $chr(47), $iif($gettok($hget(twol.games, $3), 3, 47), $gettok($hget(twol.games, $3), 3, 47))  )
        }
        ;# notify client of join
        Lw %id : $+ $+($sock(%s).mark,!u@h) JOINGAME 1 $gettok($gettok($hget(twol.games, $3), 1, 47), 2, 32) 18 1 0 $longip($gettok($hget(twol.nicks, $sock(%s).mark), 2, 58)) $iif($9 >= 1, $9, 0) $+($chr(58), $3)
        Lw %id : 332 u $3 : $+ $gettok($gettok($hget(twol.games, $3), 1, 47), 2, 58)
        ;# add where client joined in nick hash
        hadd twol.nicks $sock(%s).mark $addtok($hget(twol.nicks, $sock(%s).mark), $3, 58)
        var %i = 1, %x = $numtok($gettok($hget(twol.games, $3), 2, 47), 58), %r
        while ( %i <= %x ) {
          ;# notify client of other users
          var %n = $gettok($gettok($hget(twol.games, $3), 2, 47), %i, 58), %ci = $readini(apgar.ini, n, %n, clan)
          %r = $+($iif(%r, $+(%r, $chr(32)), $chr(58)), $iif(%n == $right($left($3, -7), -1), $+($chr(64), %n), %n), $chr(44), $iif(%ci, %ci, 0), $chr(44), $longip($gettok($hget(twol.nicks, %n), 2, 58)) )
          inc %i
        }
        Lw %id : 353 u = $3 %r
        Lw %id : 366 u $3 :
        if ( $left($3, 5) != #Lob_ ) {
          var %l = $gettok($hget(twol.games, $3), 2, 47), %x = $numtok(%l, 58), %i = 1
          while ( %i <= %x ) {
            if ( $gettok(%l, %i, 58) == $sock(%s).mark ) { goto cnext }
            ;# notify users of joining client
            Lw $gettok($hget(twol.nicks, $gettok(%l, %i, 58)), 1, 58) : $+ $+($sock(%s).mark, !u@h) JOINGAME $gettok($hget(twol.games, $3),1-5, 32) $longip($gettok($hget(twol.nicks, $sock(%s).mark), 2, 58)) 0 $+($chr(58), $3)
            :cnext
            inc %i
          }
        }
      }
      else { 
        ;# channel doesn't exists 
        Lw %id : 478 u $3
      }
    }
  }
  else if ( $2 == PART && $3 ) {
    ;# we can only part if we're in the channel
    if ( $gettok($hget(twol.nicks, $sock(%s).mark), 3, 58) == $3 ) {
      ;# remove from nick hash
      hadd twol.nicks $sock(%s).mark $remtok($hget(twol.nicks, $sock(%s).mark), $3, 58)
      if ( $left($3, 5) != #Lob_ ) {
        ;# check if channel exists because the client sends a PART if we force it to leave
        if ( $hget(twol.games, $3) ) {
          var %l = $gettok($hget(twol.games, $3), 2, 47), %x = $numtok(%l, 58), %i = 1
          while ( %i <= %x ) {
            Lw $gettok($hget(twol.nicks, $gettok(%l, %i, 58)), 1, 58) $+($chr(58), $iif($sock(%s).mark == $right($left($3, -7), -1), $gettok(%l, %i, 58), $sock(%s).mark), !u@h) PART $3
            inc %i
          }
          $iif( $right($left($3, -7), -1) == $sock(%s).mark, hdel, hadd ) twol.games $3 $+($gettok($hget(twol.games, $3), 1, 47), $chr(47), $remtok( $gettok($hget(twol.games, $3), 2, 47), $sock(%s).mark, 58 ), $chr(47), $gettok($hget(twol.games, $3), 3-, 47))
        }
      }
      else {
        Lw %id $+($chr(58), $sock(%s).mark,!u@h) PART $3
        hadd twol.lobbies $3 $remtok( $hget(twol.lobbies, $3), $sock(%s).mark, 32 )
        update.lobby $sock(%s).mark PART $3
      }
    }
  }
  else if ( $2 == PAGE ) {
    if ( $hget(twol.nicks, $3) ) {
      Lw $gettok($hget(twol.nicks, $3),1,58) $+($chr(58), $sock(%s).mark, !u@h) PAGE u $4-
      Lw %id : 389 u 0
    }
    else { Lw %id : 389 u 1 }
  }
  else if ( $2 == KICK ) {
    ;# we can only kick if we are the channel owner & if the kicked user isin the channel
    if ( $right($left($3, -7), -1) == $sock(%s).mark && $gettok($hget(twol.nicks, $4), 3, 58) == $3 ) {
      var %l = $gettok($hget(twol.games, $3), 2, 47), %x = $numtok(%l, 58), %i = 1
      while ( %i <= %x ) {
        Lw $gettok($hget(twol.nicks, $gettok(%l, %i, 58)), 1, 58) $+($chr(58), $sock(%s).mark, !u@h) KICK $3 $4 $+($chr(58), $sock(%s).mark)
        inc %i
      }
      ;# remove kicked user from game channel & from nick hash
      hadd twol.games $3 $+($gettok($hget(twol.games, $3), 1, 47), $chr(47), $remtok( $gettok($hget(twol.games, $3), 2, 47), $4, 58 ), $chr(47), $gettok($hget(twol.games, $3), 3-, 47))
      hadd twol.nicks $4 $remtok($hget(twol.nicks, $4), $3, 58)     
    }
  } 
  else if ( $2 == mode && $4 == +b ) {
    if ( $right($left($3, -7), -1) == $sock(%s).mark && $gettok($hget(twol.nicks, $5), 3, 58) == $3 ) {
      hadd twol.games $3 $gettok($hget(twol.games, $3), 1-2, 47) $+ $+($chr(47), $addtok($gettok($hget(twol.games, $3), 3, 47), $5, 58))
    }
  }
  else if ( $2 == GAMEOPT ) {
    if ( $left($3, 5) != #Lob_ ) {
      if ( $left($3, 1) == $chr(35) && $right($left($3, -7), -1) == $sock(%s).mark ) {
        var %l = $gettok($hget(twol.games, $3), 2, 47), %x = $numtok(%l, 58), %i = 1
        while ( %i <= %x ) {
          if ( $right($left($3, -7), -1) == $gettok(%l, %i, 58) ) { goto gonext }
          Lw $gettok($hget(twol.nicks, $gettok(%l, %i, 58)), 1, 58) $+($chr(58), $right($left($3, -7), -1), !u@h) GAMEOPT $3 $4-
          :gonext
          inc %i
        }
      }
      else {
        ;# TODO: need to make internal proof, client only sends <side>,<color> or <acc> gameopts and only sent from channel
        Lw $gettok($hget(twol.nicks, $iif($left($3, 1) == $chr(35), $right($left($3, -7), -1), $3)), 1, 58) $+($chr(58), $sock(%s).mark, !u@h) GAMEOPT $3 $4-
      }
    }
  }
  else if ( $2 == TOPIC && $right($left($3, -7), -1) == $sock(%s).mark ) {
    if ( $len($4-) > 3 && $numtok($4-, 44) >= 9 ) {
      var %hs = $hget(twol.games, $3)
      hadd twol.games $3 $reptok($gettok(%hs, 1, 47), $gettok($gettok(%hs, 1, 47), 2, 58), $left($4, 55), 58) $+ $+($chr(47), $gettok(%hs, 2-, 47))
    }
  }
  else if ( $2 == PRIVMSG ) { 
    if ( $left($3, 5) == #Lob_ && $gettok($hget(twol.nicks, $sock(%s).mark), 3, 58) == $3 ) {
      var %l = $hget(twol.lobbies, $3), %x = $numtok(%l, 32), %i = 1
      while ( %i <= %x ) {
        var %n = $gettok($gettok(%l, %i, 32), 1, 44)
        if ( %n == $sock(%s).mark ) { goto lnext }
        Lw $gettok($hget(twol.nicks, $iif($left(%n, 1) == $chr(64), $mid(%n, 2), %n)), 1, 58) $+($chr(58), $sock(%s).mark,!u@h) PRIVMSG $3 $4-
        :lnext
        inc %i
      }
    } 
    else if ( $left($3, 1) == $chr(35) && $gettok($hget(twol.nicks, $sock(%s).mark), 3, 58) == $3 ) {
      var %l = $gettok($hget(twol.games, $3), 2, 47), %x = $numtok(%l, 58), %i = 1
      while ( %i <= %x ) {
        if ( $gettok(%l, %i, 58) == $sock(%s).mark ) { goto gnext }
        Lw $gettok($hget(twol.nicks, $gettok(%l, %i, 58)), 1, 58) $+($sock(%s).mark,!u@h) PRIVMSG $3 $4-
        :gnext
        inc %i
      }
    }
    else {
      ;# privmsg single user
      Lw $gettok($hget(twol.nicks, $3), 1, 58) $+($chr(58), $sock(%s).mark, !u@h) PRIVMSG $3 $4-
    }
  }
  else if ( $2 == STARTG ) {
    if ( $sock(%s).mark == $right($left($3, -7), -1) ) {
      var %x = $numtok($4, 44), %r = $+($gettok($4, 1, 44), $chr(32), $gettok($hget(twol.nicks, $gettok($4, 1, 44)), 2, 58)), %i = 2
      while ( %i <= %x ) {
        %r = $+(%r, $chr(32), $gettok($4, %i, 44), $chr(32), $gettok($hget(twol.nicks, $gettok($4, %i, 44)), 2, 58))
        inc %i
      }
      var %l = $gettok($hget(twol.games, $3), 2, 47), %x = $numtok(%l, 58), %i = 1
      while ( %i <= %x ) {
        Lw $gettok($hget(twol.nicks, $gettok(%l, %i, 58)), 1, 58) $+($chr(58), twol,!u@h) PAGE u :Game Started!
        Lw $gettok($hget(twol.nicks, $gettok(%l, %i, 58)), 1, 58) $+($sock(%s).mark,!u@h) STARTG u $+($chr(58), %r) $+($chr(58), $ticks) $ctime
        .timer $+ $gettok(%l, %i, 58) 0 420 Lw $gettok($hget(twol.nicks, $gettok(%l, %i, 58)), 1, 58) $+($chr(58), PING)
        inc %i
      }
    }
  }
  else if ( $2 == SQUADINFO && $3 ) {
    var %n = $readini(clans.ini, n, $3, name)
    if ( %n ) { Lw %id : 358 u $+($3, $chr(96), %n, $chr(96), $readini(clans.ini, n, $3, abbr), $chr(96)) $+ 407688`1739712`-4262304`33`520408`540095032`0`0`0`0`x`x`x }
  }
  else if ( $2 == FINDUSEREX ) {
    if ( $len($3) <= 9 && $4 == 0 ) { 
      if ( $hget(twol.nicks, $3) ) { Lw %id : 398 u 0 $+($chr(58), $gettok($hget(twol.nicks, $3), 3, 58), $chr(44), 0) }
      else { Lw %id : 398 u 1 }
    }
  }
  else if ( $2 == QUIT ) {
    hdel twol.nicks $sock(%s).mark
    sockclose %s
  }
  else {
    ;# unhandled
    e 4UN: $+([, $sock(%s).mark, ]) $2-
  }
}

alias -l update.lobby {
  if ( $left($3, 5) == #Lob_ ) {
    var %l = $hget(twol.lobbies, $3), %x = $numtok(%l, 32), %i = 1
    while ( %i <= %x ) {
      var %n = $gettok($gettok(%l, %i, 32), 1, 44)
      if ( %n == $1 ) { goto onext }
      Lw $gettok($hget(twol.nicks, $iif($left(%n, 1) == $chr(64), $mid(%n, 2), %n)), 1, 58) $+($chr(58), $1,!u@h) $2 $3
      :onext
      inc %i
    }
    if ( $2 == JOIN ) { .timer $+ $1 off }
    ;# else if ( $2 == PART ) { timer $+ $1 0 599 Lw $gettok($hget(twol.nicks, $1), 1, 58) $+($chr(58), PING) }
  } 
}

alias -l clear.nick_instance {
  var %c = $gettok($hget(twol.nicks, $1), 3, 58)
  ;# need to boot users if hosting and remove from all locations
  if ( %c ) {
    if ( $left(%c, 5) == #Lob_ ) { hadd twol.lobbies %c $remtok( $hget(twol.lobbies, %c), $+($1, $chr(44), 0, $chr(44), 0), 32 ) | update.lobby $1 PART %c } 
    else { 
      var %l = $gettok($hget(twol.games, %c), 2, 47), %x = $numtok(%l, 58), %i = 1
      while ( %i <= %x ) {
        if ( $gettok(%l, %i, 58) == $1 ) { goto qunext }
        Lw $gettok($hget(twol.nicks, $gettok(%l, %i, 58)), 1, 58) $+($chr(58), $iif($1 == $right($left(%c, -7), -1), $gettok(%l, %i, 58), $1), !u@h) PART %c
        :qunext
        inc %i
      }
      $iif( $right($left(%c, -7), -1) == $1, hdel, hadd ) twol.games %c $+($gettok($hget(twol.games, %c), 1, 47), $chr(47), $remtok( $gettok($hget(twol.games, %c), 2, 47), $1, 58 ), $chr(47), $gettok($hget(twol.games, %c), 3-, 47))
    }
  }
  sockclose $gettok($hget(twol.nicks, $1), 1, 58)
  hdel twol.nicks $1
  .timer $+ $1 off
}

on *:sockclose:twol.L-*:{
  e 13Closed %s
  sockclose %s
}

Comments

Sign in to comment.
Gex   -  Jun 11, 2010

Good job from a good coder..what else can I say?

 Respond  
Are you sure you want to unfollow this person?
Are you sure you want to delete this?
Click "Unsubscribe" to stop receiving notices pertaining to this post.
Click "Subscribe" to resume notices pertaining to this post.