this goes in global_player.pl
http://pastebin.com/zYAhtSdz (Link for easier viewing, or see code posted below)
Code:
######################################################################################################
######################################################################################################
###
### FILE NAME : global_player.pl
### VERSION : 1.0.0
### UPDATED : Jan 15, 2014
### QUEST : Vote Kick Players
### PLUGINS REQURIED : NONE
###
### EDITS : YOU CAN SEARCH BELOW FOR SAME TEXT IN THESE COMMENTS, SEARCH FOR <EDIT HERE>
###
### MUST EDIT TELNET!! : my $ACCOUNT_NAME = "TELNET ACCOUNT"; # <--- <EDIT HERE> Make sure its unique!
### my $ACCOUNT_PASS = "PASSWORD1234"; # <--- <EDIT HERE> Add Numbers, and make sure not too long else seems to fail
###
### OPTIONAL EDITS : quest::setglobal("$QVOTE_IP","$GET_QTIME","7","S900"); # <------- <EDIT HERE>
### quest::setglobal("$QVOTE_NAME","$GET_QTIME","7","S900"); # <------- <EDIT HERE>
### my $GET_TIME_SUSPENDED = 3600; # <------- <EDIT HERE>
###
######################################################################################################
######################################################################################################
sub EVENT_SAY
{
if ($text =~/^Vote Kick$/i)
{
$client->Message(7, "Syntax: Vote Kick <name>");
}
if ($text =~/^Vote Kick /i)
{
VOTE_KICK($text);
}
if ($status > 0)
{
if ($text =~/^#Vote Kick$/i)
{
$client->Message(7, "Syntax: #Vote Kick <name> <reason>");
}
if ($text =~/^#Vote Kick /i)
{
VOTE_KICK_START($text);
}
}
}
###################################################
###################################################
###
### PLAYER VOTE KICK
###
###################################################
###################################################
sub VOTE_KICK
{
my @values = split(' ', CLEAN_TEXT_ALL($_[0]));
my $VOTE_NAME;
my @GET_STATUS;
# IF 3 VALUES THEN GET NAME
if ($values[2])
{
$VOTE_NAME = $values[2];
}
# IF WE HAVE NAME, GET ID, Proper Name, and $status
if ($VOTE_NAME)
{
my $GET_CHAR_ID = GET_ID_BY_CHARACTER($VOTE_NAME);
$VOTE_NAME = GET_CHARACTER_BY_ID($GET_CHAR_ID);
@GET_STATUS = GET_PLAYER_STATUS($VOTE_NAME);
}
my @GET_IP_ADDRESS = GET_PLAYER_STATUS($name); # 0-Status, 1-IP, 2-LoginCount
my $QVOTE_IP = "$GET_IP_ADDRESS[1]" . "_VOTED_$VOTE_NAME";
my $QVOTE_NAME = "$name" . "_VOTED_$VOTE_NAME";
my $GET_QVOTE_IP = GET_QGLOBAL_EXPIRE($QVOTE_IP);
my $GET_QVOTE_NAME = GET_QGLOBAL_EXPIRE($QVOTE_NAME);
my $GET_QTIME = time();
my $CHECK_TIME = time();
# IF PLAYER VOTED, DONT ALLOW AGAIN, UNLESS $status > 200
if ($GET_QVOTE_IP && $GET_QVOTE_IP > $CHECK_TIME && $status < 200 ||
$GET_QVOTE_NAME && $GET_QVOTE_NAME > $CHECK_TIME && $status < 200 )
{
$client->Message(7, "You already voted for $VOTE_NAME in the last 15 minutes!");
}
# ELSE SET GLOBAL AND DO VOTE
else
{
# If Guide or GM then don't allow their name to be vote kicked
if ($GET_STATUS[0] > 0)
{
$client->Message(7, "You can NOT vote kick $VOTE_NAME!");
}
# Else everyone else can be vote kicked
elsif ($VOTE_NAME)
{
$connect = LoadMySQLConnection(); # global (not 'my') cause we're going to call sub routines with while loops
my $query_handle;
my $query;
my $REQUIRED_VOTES = 5;
my $CURRENT_TIME = time();
##################################################################################
# START CHECK FOR CURRENT VOTE
$query = " SELECT kick_name, vote_count, start_vote_time
FROM _vote_kick
WHERE kick_name LIKE '$VOTE_NAME'
AND vote_count < '$REQUIRED_VOTES'
AND start_vote_time > '$CURRENT_TIME'
";
# quest::gmsay("$query", 18, 0);
$query_handle = $connect->prepare($query);
$query_handle->execute();
# IF THERE IS CURRENT VOTING THEN ADD +1 COUNT
# START GET 1 RECORD
if ($query_handle->rows)
{
my $ref = $query_handle->fetchrow_hashref();
my $GET_KICK_NAME = $ref->{'kick_name'};
my $GET_VOTE_COUNT = $ref->{'vote_count'};
my $GET_VOTE_TIME = time() - $ref->{'start_vote_time'};
$GET_VOTE_COUNT++;
quest::we(15, "$name voted to kick $GET_KICK_NAME ($GET_VOTE_COUNT / $REQUIRED_VOTES Votes Required)");
quest::setglobal("$QVOTE_IP","$GET_QTIME","7","S900"); # <------- <EDIT HERE> TIME IN SECONDS TO MAKE ANOTHER VOTE
quest::setglobal("$QVOTE_NAME","$GET_QTIME","7","S900"); # <------- <EDIT HERE> TIME IN SECONDS TO MAKE ANOTHER VOTE
if ($GET_VOTE_COUNT >= $REQUIRED_VOTES)
{
my $GET_TIME_SUSPENDED = 3600; # <------- <EDIT HERE> TIME IN SECONDS TO BE SUSPENDED
my $GET_SUSPEND_TIME = (time + $GET_TIME_SUSPENDED);
my @GET_NAMES = WHO_IS_PLAYER_LIST($GET_KICK_NAME); # Get all characters linked by account and IP.
quest::we(7, "$GET_KICK_NAME has been kicked for $GET_TIME_SUSPENDED seconds!");
my $i = 0;
while ($GET_NAMES[$i])
{
SUSPEND_PLAYER_NAME($GET_NAMES[$i], $GET_SUSPEND_TIME);
quest::gmsay("GM: $GET_NAMES[$i] has been suspended! (VOTE_KICK)", 13, 1);
$i++;
}
$i--;
quest::gmsay("GM: $i characters has been suspended! (VOTE_KICK)", 13, 1);
# DISCONNECT ALL CHARACTERS LINKED BY IP IMMEDIATELY!
KICK_PLAYER_NAME(\@GET_NAMES);
}
$query = " UPDATE _vote_kick
SET vote_count = '$GET_VOTE_COUNT'
WHERE kick_name LIKE '$GET_KICK_NAME'
";
# quest::gmsay("$query", 18, 0);
$query_handle = $connect->prepare($query);
$query_handle->execute();
}
# END CHECK FOR CURRENT VOTE
##################################################################################
# ELSE NO VOTE STARTED YET
else
{
$client->Message(7, "Voting for $VOTE_NAME has not started yet.");
}
$query_handle->finish();
$connect->disconnect();
}
else
{
$client->Message(7, "Syntax: Vote Kick <name>");
}
} # End Else Not Voted Yet
return 1;
} # End VOTE_KICK
###################################################
###################################################
###
### GM AND GUIDE VOTE KICK
###
###################################################
###################################################
sub VOTE_KICK_START
{
my @values = split(' ', CLEAN_TEXT_ALL($_[0]));
my $VOTE_NAME;
my $VOTE_REASON;
my @GET_STATUS;
# IF 3 VALUES THEN GET NAME
if ($values[2])
{
$VOTE_NAME = $values[2];
}
if ($VOTE_NAME)
{
my $GET_CHAR_ID = GET_ID_BY_CHARACTER($VOTE_NAME);
$VOTE_NAME = GET_CHARACTER_BY_ID($GET_CHAR_ID);
@GET_STATUS = GET_PLAYER_STATUS($VOTE_NAME);
}
# If Guide or GM then don't allow their name to be vote kicked
if ($GET_STATUS[0] > 0)
{
$client->Message(7, "You can NOT vote kick $VOTE_NAME!");
}
# Else everyone else can be vote kicked
elsif ($VOTE_NAME)
{
my $connect = LoadMySQLConnection();
my $query_handle;
my $query;
my $REQUIRED_VOTES = 5;
my $CURRENT_TIME = time();
##################################################################################
# START CHECK FOR CURRENT VOTE
$query = " SELECT kick_name, vote_count, start_vote_time
FROM _vote_kick
WHERE kick_name LIKE '$VOTE_NAME'
AND vote_count < '$REQUIRED_VOTES'
AND start_vote_time > '$CURRENT_TIME'
";
# quest::gmsay("$query", 18, 0);
$query_handle = $connect->prepare($query);
$query_handle->execute();
# IF CURRENT VOTING, DONT MAKE NEW ONE
if ($query_handle->rows)
{
my $ref = $query_handle->fetchrow_hashref();
my $GET_KICK_NAME = $ref->{'kick_name'};
my $GET_VOTE_COUNT = $ref->{'vote_count'};
my $GET_VOTE_TIME = time() - $ref->{'start_vote_time'};
$client->Message(7, "$GET_KICK_NAME already has $GET_VOTE_COUNT votes and expires in $GET_VOTE_TIME seconds.");
}
# END CHECK FOR CURRENT VOTE
##################################################################################
# ELSE NO CURRENT VOTE, LETS MAKE ONE
else
{
my $GET_DATETIME = CUSTOM_DATE_TIME(time());
my $GET_VOTE_COUNT = 0;
my $GET_REASON = "";
# IF 4+ VALUES THEN GET REASON FOR KICK
if ($values[3])
{
# Add (concat) all words to the reason
my $i = 3;
while ($values[$i])
{
if ($i > 3)
{
$GET_REASON .= " ";
}
$GET_REASON .= "$values[$i]";
$i++;
}
}
# ELSE NO REASON GIVEN FOR KICK
else
{
$GET_REASON = "None Given";
}
my $GET_START = time() + 900;
my $query = " REPLACE INTO _vote_kick (datetime, mod_name, kick_name, vote_count, reason, start_vote_time)
VALUES ('$GET_DATETIME', '$name', '$VOTE_NAME', '$GET_VOTE_COUNT', '$GET_REASON', '$GET_START')";
# quest::gmsay("$query", 18, 0);
$query_handle = $connect->prepare($query);
$query_handle->execute();
$client->Message(7, "Vote Kick $VOTE_NAME Started!");
quest::we(15, "/say Vote Kick $VOTE_NAME (Reason: $GET_REASON)");
}
$query_handle->finish();
$connect->disconnect();
}
else
{
$client->Message(7, "Syntax: #Vote Kick <name> <reason>");
}
return 1;
} # End VOTE_KICK_START
# GET ACCOUNT ID VIA PLAYER NAME
sub GET_PLAYER_ACCOUNT_ID
{
my $FIND_TOON_NAME = CLEAN_TEXT_ALL($_[0]);
my $GET_ID = 0;
my $connect = LoadMySQLConnection();
my $query = " SELECT DISTINCT a.id
FROM account a
INNER JOIN character_ c ON c.account_id = a.id
WHERE c.name LIKE '$FIND_TOON_NAME'
LIMIT 1";
my $query_handle = $connect->prepare($query);
$query_handle->execute();
if ($query_handle->rows)
{
my $ref = $query_handle->fetchrow_hashref();
$GET_ID = $ref->{'id'};
}
$query_handle->finish();
$connect->disconnect();
return $GET_ID;
} # End GET_PLAYER_ACCOUNT_ID
sub SUSPEND_PLAYER_NAME
{
# If at least 2 parameters (Name + Time)
if ($_[1])
{
my $GET_NAME = $_[0];
my $GET_TIME = SUSPEND_DATE(CLEAN_NUMBER($_[1]));
my $GET_ACCOUNT_ID = GET_PLAYER_ACCOUNT_ID($GET_NAME);
if ($GET_ACCOUNT_ID)
{
# SET SUSPENSION TIME
# my $connect = LoadMySQLConnection(); # DONE BY PARENT ROUTINE
my $query = " UPDATE account SET suspendeduntil = '$GET_TIME' WHERE id = '$GET_ACCOUNT_ID'";
# quest::gmsay("$query", 18, 1);
$query_handle = $connect->prepare($query);
$query_handle->execute();
$query_handle->finish();
# $connect->disconnect(); # DONE BY PARENT ROUTINE
}
else
{
quest::gmsay("SUSPEND_PLAYER_NAME ERROR! NO ACCOUNT ID FOR $_[0]", 18, 1);
}
}
else
{
quest::gmsay("SUSPEND_PLAYER_NAME ERROR! DOES NOT HAVE 2ND PARAMETER! $_[0] $_[1]", 18, 1);
}
return 1;
} # End SUSPEND_PLAYER_NAME
# Special Date/Time format for suspenduntil field in account table
sub SUSPEND_DATE
{
my $CONVERT_TIME = 0;
if ($_[0])
{
$CONVERT_TIME = $_[0];
}
else
{
$CONVERT_TIME = time();
}
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($CONVERT_TIME);
$mon++; # Required
$mon = sprintf("%02d", $mon);
$mday = sprintf("%02d", $mday);
$year = sprintf("%02d", $year % 100) + 2000;
$hour = sprintf("%02d", $hour);
$min = sprintf("%02d", $min);
$sec = sprintf("%02d", $sec);
# RETURN FORMAT: 2014-12-31 23:59:59
my $RETURN_DATE = "$year" . "-" . "$mon" . "-" . "$mday" . " " . " $hour:$min:$sec";
return $RETURN_DATE;
} # End SUSPEND_DATE()
# CUSTOM FORMATTED DATE AND TIME
sub CUSTOM_DATE_TIME
{
my $CONVERT_TIME = 0;
if ($_[0])
{
$CONVERT_TIME = $_[0];
}
else
{
$CONVERT_TIME = time();
}
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($CONVERT_TIME);
$mon++; # Required
$mon = sprintf("%02d", $mon);
$mday = sprintf("%02d", $mday);
$year = sprintf("%02d", $year % 100);
$hour = sprintf("%02d", $hour);
$min = sprintf("%02d", $min);
$sec = sprintf("%02d", $sec);
# RETURN FORMAT: 01-31-14 23:59:59
my $ez_time = "$mon" . "-" . "$mday" . "-" . "$year" . " $hour:$min:$sec";
return $ez_time;
} # End CUSTOM_DATE_TIME()
# Instantly kick player offline by logging in with Telnet
sub KICK_PLAYER_NAME
{
my @GET_NAMES = @{$_[0]};
use Net::Telnet();
my $telnet;
$telnet = new Net::Telnet (Timeout=>10, Port=>'9000', Prompt=>'/\> $/');
$telnet->open("localhost");
##########################################################################
# I NOTICED LOGIN CAN BE PICKY
# ACCOUNT NAME : LIKE TO USE A SPACE IN THE ACCOUT NAME
# PASSWORD : PASSWORD1234 SEEMS TO WORK,
# BUT NOT PASSWORD12345678, MAYBE TOO LONG?
# MAKE SURE THE ACCOUNT NAME HAS 255 STATUS IN ACCOUNT TABLE
##########################################################################
my $ACCOUNT_NAME = "TELNET ACCOUNT"; # <--- <EDIT HERE> Make sure its unique!
my $ACCOUNT_PASS = "PASSWORD1234"; # <--- <EDIT HERE> Add Numbers, and make sure not too long else seems to fail
$telnet->login("$ACCOUNT_NAME", "$ACCOUNT_PASS");
my $i = 0;
while ($GET_NAMES[$i])
{
$telnet->cmd("kick $GET_NAMES[$i]");
quest::gmsay("GM: $GET_NAMES[$i] has been kicked! (KICK_PLAYER_NAME)", 4, 1);
$i++;
}
$i--;
quest::gmsay("GM: $i characters has been kicked! (KICK_PLAYER_NAME)", 4, 1);
exit;
} # End KICK_PLAYER_NAME
sub WHO_IS_PLAYER_LIST
{
# my $connect = LoadMySQLConnection(); # CREATED BY PARENT ROUTINE
my $FIND_TOON_NAME = $_[0];
my @LIST_OF_TOONS;
my $query = " SELECT DISTINCT a_ip.ip
FROM account a
INNER JOIN account_ip a_ip ON a_ip.accid = a.id
INNER JOIN character_ c ON c.account_id = a.id
WHERE c.name LIKE '$FIND_TOON_NAME'
ORDER BY a_ip.lastused DESC
LIMIT 1";
# quest::gmsay("$query", 18, 0);
my $query_handle = $connect->prepare($query);
$query_handle->execute();
# START GET 1 RECORD
if ($query_handle->rows)
{
my $ref = $query_handle->fetchrow_hashref();
my $GET_IP = $ref->{'ip'};
my $query2 = " SELECT DISTINCT c.name
FROM account a
INNER JOIN account_ip a_ip ON a_ip.accid = a.id
INNER JOIN character_ c ON c.account_id = a.id
WHERE a_ip.ip LIKE '$GET_IP'
ORDER BY c.name ASC
LIMIT 200";
# quest::gmsay("$query2", 18, 0);
my $query_handle2 = $connect->prepare($query2);
$query_handle2->execute();
my $place_count = 0;
while(my $ref2 = $query_handle2->fetchrow_hashref)
{
my $SHOW_NAME = $ref2->{'name'};
push (@LIST_OF_TOONS, $SHOW_NAME);
$place_count++;
}
$place_count--;
quest::gmsay("GM: WHO_IS_PLAYER_LIST Results : $place_count Toons Total.", 18, 1);
$query_handle2->finish();
}
else
{
quest::gmsay("GM: WHO_IS_PLAYER_LIST LIST : $FIND_TOON_NAME NOT FOUND!", 18, 1);
}
# END GET 1 RECORD
$query_handle->finish();
# $connect->disconnect(); # DONE BY PARENT ROUTINE
return @LIST_OF_TOONS;
} # End WHO_IS_PLAYER_LIST()
# Very Simple: Get Qglobal `expdate` of `name` and Return it
sub GET_QGLOBAL_EXPIRE
{
my $connect = LoadMySQLConnection();
my $qglobal_name = $_[0];
my $a_name = "NULL";
my $b_value = "0";
my $query = "SELECT name, expdate FROM quest_globals WHERE name = '$qglobal_name' LIMIT 1";
my $query_handle = $connect->prepare($query);
$query_handle->execute();
if ($query_handle->rows)
{
my $ref = $query_handle->fetchrow_hashref();
$a_name = $ref->{'name'};
$b_value = $ref->{'expdate'};
}
$query_handle->finish();
$connect->disconnect();
return $b_value;
} # End GET_QGLOBAL_EXPIRE()
### RETURN CHARACTERS NAME
sub GET_CHARACTER_BY_ID
{
if ($_[0])
{
my $connect = LoadMySQLConnection();
my $CHECK_CHARID = $_[0];
my $RETURN_NAME = "";
my $query = "SELECT name FROM character_ WHERE id = '$CHECK_CHARID' LIMIT 1";
my $query_handle = $connect->prepare($query);
$query_handle->execute();
if ($query_handle->rows)
{
my $ref = $query_handle->fetchrow_hashref();
$RETURN_NAME = $ref->{'name'};
}
$query_handle->finish();
$connect->disconnect();
return $RETURN_NAME;
}
} # End GET_CHARACTER_BY_ID()
### RETURN CHARACTERS ID
sub GET_ID_BY_CHARACTER
{
if ($_[0])
{
my $connect = LoadMySQLConnection();
my $CHECK_CHAR_NAME = $_[0];
my $RETURN_ID = 0;
my $query = "SELECT id FROM character_ WHERE name LIKE '$CHECK_CHAR_NAME' LIMIT 1";
my $query_handle = $connect->prepare($query);
$query_handle->execute();
if ($query_handle->rows)
{
my $ref = $query_handle->fetchrow_hashref();
$RETURN_ID = $ref->{'id'};
}
$query_handle->finish();
$connect->disconnect();
return $RETURN_ID;
}
} # End GET_ID_BY_CHARACTER()
sub GET_PLAYER_STATUS
{
my $GET_NAME = $_[0];
my @GET_STATUS;
my $connect = LoadMySQLConnection();
my $query = " SELECT DISTINCT a.status, a_ip.ip, SUM(a_ip.count)
FROM account a
INNER JOIN account_ip a_ip ON a_ip.accid = a.id
INNER JOIN character_ c ON c.account_id = a.id
WHERE c.name LIKE '$GET_NAME'
ORDER BY a_ip.lastused DESC
LIMIT 1";
my $query_handle = $connect->prepare($query);
$query_handle->execute();
# START GET 1 RECORD
if ($query_handle->rows)
{
# quest::gmsay("GM: HAS STATUS", 18, 0);
my $ref = $query_handle->fetchrow_hashref();
my $GET_ACCOUNT_STATUS = $ref->{'status'};
my $GET_IP_ADDRESS = $ref->{'ip'};
my $LOGIN_COUNT = $ref->{'SUM(a_ip.count)'}; # For another GM tool I have.
# Get $status value from account table
if (defined($GET_ACCOUNT_STATUS))
{
push(@GET_STATUS, $GET_ACCOUNT_STATUS);
}
else
{
push(@GET_STATUS, "NA");
}
# Get IP address from account_ip table
if ($GET_IP_ADDRESS)
{
push(@GET_STATUS, $GET_IP_ADDRESS);
}
else
{
push(@GET_STATUS, "NA");
}
# Get number of times logged in total by IP from account_ip table
if (defined($LOGIN_COUNT))
{
push(@GET_STATUS, $LOGIN_COUNT);
# quest::gmsay("GM: LOGIN COUNT: $LOGIN_COUNT", 18, 0);
}
else
{
push(@GET_STATUS, "NA");
}
}
# END GET 1 RECORD
else
{
# quest::gmsay("GM: $GET_NAME HAS -NO- STATUS", 18, 0);
push(@GET_STATUS, "NA");
push(@GET_STATUS, "NA");
push(@GET_STATUS, "NA");
}
$query_handle->finish();
$connect->disconnect();
return @GET_STATUS;
} # End GET_PLAYER_STATUS
sub CLEAN_TEXT_ALL
{
local $_ = shift;
s/[^a-zA-Z0-9(). ]+//g;
return $_;
}
sub CLEAN_TEXT
{
local $_ = shift;
s/[^a-zA-Z]+//g;
return $_;
}
sub CLEAN_NUMBER
{
local $_ = shift;
s/[^0-9]+//g;
return $_;
}
### Establish a Connection with password from Config File
sub LoadMySQLConnection
{
use DBI;
use DBD::mysql;
my $confile = "eqemu_config.xml"; #default config file in server folder has user and pass
open(F, "<$confile") or quest::gmsay("GM: sub LoadMySQLConnection() 'open' FAILED !!!!", 15, 1);
my $indb = 0;
while(<F>)
{
s/\r//g;
if(/<database>/i) { $indb = 1; }
next unless($indb == 1);
if(/<\/database>/i) { $indb = 0; last; }
if(/<host>(.*)<\/host>/i) { $host = $1; }
elsif(/<username>(.*)<\/username>/i) { $user = $1; }
elsif(/<password>(.*)<\/password>/i) { $pass = $1; }
elsif(/<db>(.*)<\/db>/i) { $db = $1; }
}
my $dsn = "dbi:mysql:$db:localhost:3306";
my $connect = DBI->connect($dsn, $user, $pass) or quest::gmsay("GM: sub LoadMySQLConnection() 'connect' FAILED !!!!", 15, 1);
return $connect;
} # End LoadMySQLConnection()
this creates the table required
Code:
CREATE TABLE `_vote_kick` (
`datetime` text NOT NULL,
`mod_name` varchar(65) NOT NULL DEFAULT '',
`kick_name` varchar(65) NOT NULL DEFAULT '',
`vote_count` int(11) NOT NULL DEFAULT '0',
`reason` text NOT NULL,
`start_vote_time` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`kick_name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|