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
}