📄 functions.in
字号:
@ARGV = split /\s+/, $line, 3; tellcmd($handle, $ARGV[1], $ARGV[2]); } elsif(cmd("times", $line)) { @ARGV = split /\s+/, $line, 3; timestamps($handle, $ARGV[1]); } elsif(cmd("ping", $line)) { @ARGV = split /\s+/, $line, 3; ping($handle, $ARGV[1]); } elsif(cmd("invite", $line)) { @ARGV = split /\s+/, $line, 3; invite($handle, $ARGV[1]); } elsif(cmd("ignore", $line)) { @ARGV = split /\s+/, $line, 4; ignore($handle, $ARGV[1], $ARGV[2]); } elsif(cmd("me", $line)) { if($handles{$handle}{flag} != 5) { notOn($handle); } else { @ARGV = split /\s+/, $line, 2; $handles{$handle}{spoke} = time(); ++$stats{spoken}; ++$handles{$handle}{spoken}; my $username = $handles{$handle}{username}; $ARGV[0] =~ s/^\/me?/$username/; if($handles{$handle}{write} == 0) { toHandle($handle, "", "<".dateStr()."> ", "$ARGV[0] " . $ARGV[1]); } else { broadcastChan($handle, $handles{$handle}{channel}, "", "<" . dateStr() . "> ", "$ARGV[0] " . $ARGV[1]); } } } elsif(cmd("nuclear", $line)) { if($handles{$handle}{flag} != 5) { notOn($handle); } else { @ARGV = split /\s+/, $line, 2; ++$stats{spoken}; ++$handles{$handle}{spoken}; $ARGV[1] =~ s/[<>]//g; if($handles{$handle}{write} == 0) { toHandle($handle, $ARGV[1]); } else { broadcastChan($handle, $handles{$handle}{channel}, $ARGV[1]); } } } elsif(cmd("username", $line)) { @ARGV = split /\s+/, $line, 3; username($handle, $ARGV[1]); } elsif($line =~ /^\//) { toHandle($handle, "", "<".dateStr()."> ", "* Invalid command."); } elsif($handles{$handle}{flag} == 5) { $handles{$handle}{spoke} = time(); ++$stats{spoken}; ++$handles{$handle}{spoken}; my $username = $handles{$handle}{username}; if($handles{$handle}{write} == 0) { toHandle($handle, "<", dateStr()." ", "$username> " . $line); } else { broadcastChan($handle, $handles{$handle}{channel}, "<", dateStr() . " ", "$username> " . $line); } } else { notOn($handle); }}# *** removeHandle() ***# Accepts a filehandle name as input and closes that handle, deletes it from# the lists of active handles, and logs a message to that effect.sub removeHandle { my $handle = shift; my $username = $handles{$handle}{username}; my $logmsg = "Removing handle $handle "; if(defined($username)) { $logmsg .= "($username)."; } else { $logmsg .= "(no username provided)."; } logmsg("USER: $logmsg"); signoff($username) if $handles{$handle}{flag} == 5; close $handle; delete $handles{$handle}; delete $users{$username} if defined($username); setbits();}# *** runCode() ***# Runs some arbitrary code sent in.sub runCode { my ($handle, $line) = @_; my $logmsg; if(exists $handles{$handle}{username}) { $logmsg = $handles{$handle}{username}; } else { $logmsg = $handle; } $logmsg .= " executed the following code: $line"; logmsg("CODE: $logmsg"); eval "$line";}# *** serverKill() ***# Shuts down the server quasi-gracefully.sub serverKill { logmsg "SERVER: Shutting down."; logmsg "SERVER: Closing incoming socket."; close(Server); broadcastMsg("*", dateStr() . "*", " geektalkd is shutting down."); logmsg "SERVER: Kicking off all users."; foreach(keys %handles) { removeHandle($_); } logmsg "SERVER: Exiting."; exit;}# *** serverStats() ***# Sends the user stats about the server (called from stats())sub serverStats { my $handle = shift; toHandle($handle, "*", " ".dateStr()); toHandle($handle, "* Geektalkd Server Statistics:"); toHandle($handle, "* Server version $VERSION"); toHandle($handle, "* Functions version $FUNCVERS ($FUNCDATE)"); toHandle($handle, "* Server started on " . scalar(localtime($stats{start}))); my $stat = timeDiff($stats{start}, time(), 1); toHandle($handle, "* Server running $stat"); toHandle($handle, "* Total number of connections: $filenum"); $stat = keys %handles; toHandle($handle, "* Current open connections: $stat"); $stat = 0; foreach (keys %users) { ++$stat if $users{$_}{flag} > 3; } toHandle($handle, "* Current users: $stat"); toHandle($handle, "* Total number of /signons: $stats{signon}"); toHandle($handle, "* Total number of lines processed: $stats{lines}"); $stat = int($stats{lines}/((time() - $stats{start})/3600)); toHandle($handle, "* Lines processed per hour: $stat"); toHandle($handle, "* Total number of lines spoken: $stats{spoken}"); $stat = int($stats{spoken}/((time() - $stats{start})/3600)); toHandle($handle, "* Lines spoken per hour: $stat"); toHandle($handle, "*");}# *** setbits() ***# Accepts a list of filehandles and returns a vector bitstream of those handles# for use with select();sub setbits { my @fhlist = ("Server", keys %handles); $bits = ""; for (@fhlist) { vec($bits, fileno($_), 1) = 1; } return $bits;}# *** signoff() ***# Signs off a username passed as an argument.sub signoff { my $username = shift; broadcastMsg("|", dateStr() . " ", "signoff| $username\@$users{$username}{hostname} ($username)"); $users{$username}{flag} = 4; $users{$username}{spoke} = time();}# *** signon() ***# Signs on a username passed as an argument.sub signon { my ($username, $channel) = @_; $users{$username}{flag} = 5; $users{$username}{spoke} = time(); ++$stats{signon}; if(defined $channel) { $users{$username}{channel} = $channel; } elsif($users{$username}{channel} == 0) { $users{$username}{channel} = 1; } broadcastMsg("|", dateStr() . " ", "signon| $username\@$users{$username}{hostname} ($username)");}# *** stats() ***# Print out some server statistics.sub stats { my ($handle, $name) = @_; if(!defined $name) { serverStats($handle); } elsif(!exists $users{$name}) { toHandle($handle, "*", dateStr() . "*", " No such user."); } else { userStats($handle, $name); }}# *** tellcmd() ***# Accepts a user to tell from, and a user to tell to, and a message.sub tellcmd { my ($from, $to, $message) = @_; if ($handles{$from}{flag} != 5) { notOn($from); } elsif(!exists $users{$to}) { toHandle($from, "", "<".dateStr()."> ", "* User not found."); } elsif($users{$to}{flag} != 5) { toHandle($from, "", "<".dateStr()."> ", "* User is not signed on."); } elsif(!defined $message) { toHandle($from, "", "<".dateStr()."> ", "* No message."); } else { my $fromname = $handles{$from}{username}; my $tohandle = $users{$to}{handle}; toHandle($from, "", "<".dateStr()."> ", "* you tell $to: $message"); if(!exists $users{$to}{ignore}{$handles{$from}{username}}) { toHandle($tohandle, "", "<".dateStr()."> ", "\a\a* $fromname tells you: $message"); } }}# *** timeDiff ***# Returns a brief time diference (55d23h || 23h 6m || 54m)sub timeDiff { my ($orig, $new, $full) = @_; my $idlestr; my $diff = $new - $orig; my $days = int($diff / 86400); $diff %= 86400; my $hours = int($diff / 3600); $diff %= 3600; my $mins = int($diff / 60); if(defined $full) { return(sprintf("%dd%2dh%2dm", $days, $hours, $mins)); } elsif($days > 0) { return(sprintf("%2dd%2dh", $days, $hours)); } elsif($hours > 0) { return(sprintf("%2dh%2dm", $hours, $mins)); } else { return(sprintf("%2dm", $mins)); }}# *** times() ***# Accepts a handle and another argument, and turns timestamps on or off.sub timestamps { my ($handle, $boolean) = @_; $boolean = lc($boolean); if($handles{$handle}{flag} != 5) { notOn($handle); } elsif((!defined $boolean || $boolean eq "") && $boolean ne "on" && $boolean ne "off" && $boolean ne "1" && $boolean ne "0") { if($handles{$handle}{times} == 0) { $handles{$handle}{times} = 1; toHandle($handle, "", "<".dateStr()."> ", "* Timestamps are now ON."); } else { $handles{$handle}{times} = 0; toHandle($handle, "", "<".dateStr()."> ", "* Timestamps are now OFF."); } } elsif($boolean eq "on" || $boolean eq "1") { $handles{$handle}{times} = 1; toHandle($handle, "", "<".dateStr()."> ", "* Timestamps are now ON."); } elsif($boolean eq "off" || $boolean eq "0") { $handles{$handle}{times} = 0; toHandle($handle, "", "<".dateStr()."> ", "* Timestamps are now OFF."); } else { toHandle($handle, "", "<".dateStr()."> ", "* Invalid argument."); }}# *** toHandle() ***# Sends a line of data to a specific handle.sub toHandle { my ($handle, $pretime, $time, $posttime) = @_; if(defined $time && $handles{$handle}{times} == 1) { $pretime .= $time; } $pretime .= $posttime if(defined $posttime); print $handle $pretime, "\r\n";}sub username { my ($handle, $new) = @_; if($handles{$handle}{flag} < 4) { notOn($handle); } else { my $old = $handles{$handle}{username}; if($new eq $old) { toHandle($handle, "", "<".dateStr()."> ", "* That already IS your username!"); } elsif(!defined $new || $new eq '') { toHandle($handle, "", "<".dateStr()."> ", "* You must specify a new username."); } elsif($new =~ /^[A-Za-z0-9_\-\.]{1,15}$/) { if(exists $users{$new}) { toHandle($handle, "", "<".dateStr()."> ", "* That username is already taken."); } else { $handles{$handle}{username} = $new; $users{$new} = $handles{$handle}; delete $users{$old}; if($handles{$handle}{flag} == 5) { broadcastMsg("|", dateStr() . "| $old is now known as $new."); } } } else { toHandle($handle, "", "<".dateStr()."> ", '* Invalid username. Valid usernames are from the set /^[A-Za-z0-9_\-\.]{1,15}$/'); } }}# *** userStats() ***# Sends the user stats about the requested user (called from stats())sub userStats { my ($handle, $name) = @_; my $connection = ""; toHandle($handle, "*", " ".dateStr()); toHandle($handle, "* $name User Statistics:"); toHandle($handle, "* User connected on " . scalar(localtime($users{$name}{connect}))); my $stat = timeDiff($users{$name}{connect}, time(), 1); toHandle($handle, "* User connected $stat");##@ $connection = $users{$name}{ident} ?##@ "$users{$name}{ident}\@" : "unknown\@"; $connection .= $users{$name}{rhostname} ? "$users{$name}{rhostname}:" : "$users{$name}{ipaddr}:"; $connection .= "$users{$name}{rport}"; toHandle($handle, "* User connected from $connection"); toHandle($handle, "* User last spoke at " . scalar(localtime($users{$name}{spoke}))); $stat = timeDiff($users{$name}{spoke}, time(), 1); toHandle($handle, "* User is idle $stat"); toHandle($handle, "* Total number of lines processed: $users{$name}{lines}"); $stat = int($users{$name}{lines}/((time() - $users{$name}{connect})/3600)); toHandle($handle, "* Lines processed per hour: $stat"); toHandle($handle, "* Total number of lines spoken: $users{$name}{spoken}"); $stat = int($users{$name}{spoken}/((time() - $users{$name}{connect})/3600)); toHandle($handle, "* Lines spoken per hour: $stat"); if($users{$name}{flag} < 5) { $stat = "offline"; } elsif($users{$name}{channel} < 0) { $stat = "private"; } else { $stat = $users{$name}{channel}; } toHandle($handle, "* Channel: $stat"); $stat = $users{$name}{echo} ? "On" : "Off"; toHandle($handle, "* Echoing: $stat"); $stat = $users{$name}{times} ? "On" : "Off"; toHandle($handle, "* Timestamps: $stat"); toHandle($handle, "*");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -