You can change several options below "# you can change some of this plugin settings below !" line. Just search for it inside the code.
Console commands:
whitelist management
Usage: \n\n".
Add player : whitelist <username>\n".
Remove player : whitelist rem <username>\n".
Clear whitelist.txt : whitelist clear\n".
Print whitelist content : whitelist print\n".
Syntax help : whitelist ?, whitelist help\n"
blacklist management
Add and block player : blacklist <username>\n".
Remove player : blacklist rem <username>\n".
Clear blacklist.txt : blacklist clear\n".
Print blacklist content : blacklist print\n".
Syntax help : blacklist ?, blacklist help\n"
Code: Select all
#############################################################################
# leaveMeAlone! revision 04 plugin by imikelance
#
# Openkore: http://openkore.com/
# Openkore Brazil: http://openkore.com.br/
#
# 16:20 segunda-feira, 20 de fevereiro de 2012
# - changed default block queue from AI-dependent to non-AI-dependent. now we won't flood AI.
# - added AI_MODE to revert back to AI-dependent block queue
# - now we won't re-block players on map change
#
# 10:50 segunda-feira, 30 de janeiro de 2012
# - changed AI_pre hook to mainLoop_pre
#
# 06:05 segunda-feira, 30 de janeiro de 2012
# - added whitelist sub commands
# - added blacklist command
# - now block users command is queued into kore's AI
# - won't keep opening and closing .txt, now we're storing DBs into @blacklist and @whitelist
# - added BLOCKDELAY constant to avoid DCs
# - auto create files and folders
# - added checks to detect .txt files changes
# - added commands help, use "whitelist help" and "blacklist help"
# - added checks to verify if we're blocking a "whitelisted" user
# - [DEV] added AI_pre hook
# - [DEV] added sub msg to handle console messages properly
#
# 17:08 sexta-feira, 27 de janeiro de 2012
# - added whitelist.txt and whitelist command
#
# 06:22 sexta-feira, 27 de janeiro de 2012
# - released !
#
# This source code is licensed under the
# GNU General Public License, Version 3.
# See http://www.gnu.org/licenses/gpl.html
#############################################################################
package leaveMeAlone;
use strict;
use Plugins;
use Actor;
use Log qw( warning message error );
use Time::HiRes qw(time);
use AI;
# Plugin
Plugins::register("leaveMeAlone", "keeps a list of ignored players and block spammers", \&unload);
my $myHooks = Plugins::addHooks(
#['start3', \&start, undef],
['packet_privMsg', \&messages, undef],
['packet_pubMsg', \&messages, undef],
['in_game', \&ingame],
['mainLoop_pre', \&AI_hook], # AI_pre freezes if AI = manual
['packet/received_characters', \&turnOn],
);
my $myCmds = Commands::register(
['whitelist', "Use \"whitelist help\" for instructions.", \&comm_White],
['blacklist', "Use \"whitelist help\" for instructions.", \&comm_Black],
['block', "Use \"blacklist\" instead of this.", \&comm_Block],
['unblock', "Use \"blacklist rm\" instead of this.", \&comm_Unblock],
);
my $workingFolder = $Plugins::current_plugin_folder;
my %userlist;
my $lastblocktime;
my %lastAccess;
my @whitelist;
my @blacklist;
my $mustBlock;
my $blacklist_pos;
# LOAD WHITE AND BLACKLIST
&start;
# you can change some of this plugin settings below !
use constant {
PLUGINNAME => "leaveMeAlone",
# set to 1 to show debug messages
DEBUG => 0,
# disable almost every message. error messages will still be shown
SILENT => 0,
#### SPAM BLOCKING OPTIONS ###
# self-explaining.
DISABLESPAMCHECKS => 0,
# if set to 1, won't check players with guilds for spamming
SPAMONLYGUILDLESS => 1,
# start checking PM/second after receiving <value> PMs
MINPMCOUNT => 2,
# if character exceeds <value> PMs per seconds will be considered a SPAMMER
MAXPMPERSECOND => 1.2,
# reset data about character that has not sent any PMs in the last <value> seconds
RESETCOUNT => 4,
# even zero should be fine, but you can increase this if you're having trouble with DCs
BLOCKDELAY => 0.3,
# queue blocks into AI if set to 1
AI_MODE => 0,
};
# Plugin unload
sub unload {
message("\nleaveMeAlone unloading.\n\n");
Plugins::delHooks($myHooks);
Commands::unregister($myCmds);
undef $myHooks;
undef $myCmds;
undef @whitelist;
undef @blacklist;
undef $workingFolder;
undef %userlist;
undef $lastblocktime;
undef $blacklist_pos;
}
# Subs
sub turnOn {
$mustBlock = 1;
$blacklist_pos = 0;
$lastblocktime = Time::HiRes::time + (BLOCKDELAY * 4);
}
sub start {
unless (-d $workingFolder."/leaveMeAlone/") {
mkdir ($workingFolder."/leaveMeAlone/");
}
unless (-e $workingFolder."/leaveMeAlone/blacklist.txt") {
open BLACKLIST, ">:utf8", $workingFolder."/leaveMeAlone/blacklist.txt";
close BLACKLIST;
}
unless (-e $workingFolder."/leaveMeAlone/whitelist.txt") {
open WHITELIST, ">:utf8", $workingFolder."/leaveMeAlone/whitelist.txt";
close WHITELIST;
}
&load_whitelist;
&load_blacklist;
}
sub load_blacklist {
undef @blacklist;
open BLACKLIST, "<:utf8", $workingFolder."/leaveMeAlone/blacklist.txt"
or die "cannot open ".$workingFolder."/leaveMeAlone/blacklist.txt: $!";
while (<BLACKLIST>) {
chomp;
my $currline = $_;
$currline =~ s/^\s*//; $currline =~ s/\s*$//;
if (($currline !~ /^#/) and ($currline ne "")){
push(@blacklist, $currline);
}
}
close BLACKLIST;
$lastAccess{blacklist}{path} = $workingFolder."/leaveMeAlone/blacklist.txt";
$lastAccess{blacklist}{lastSize} = -s $lastAccess{blacklist}{path};
msg("[".PLUGINNAME."] Blacklist loaded ! \n",0,1);
}
sub load_whitelist {
undef @whitelist;
open WHITELIST, "<:utf8", $workingFolder."/leaveMeAlone/whitelist.txt"
or die "cannot open ".$workingFolder."/leaveMeAlone/whitelist.txt: $!";
while (<WHITELIST>) {
chomp;
my $currline = $_;
$currline =~ s/^\s*//; $currline =~ s/\s*$//;
if (($currline !~ /^#/) and ($currline ne "")){
push(@whitelist, $currline);
}
}
close WHITELIST;
$lastAccess{whitelist}{path} = $workingFolder."/leaveMeAlone/whitelist.txt";
$lastAccess{whitelist}{lastSize} = -s $lastAccess{whitelist}{path};
msg("[".PLUGINNAME."] Whitelist loaded ! \n",0,1);
}
sub ingame {
if ($mustBlock) {
lastAccessVerify(1);
if (AI_MODE) {
foreach (@blacklist) {
my %args;
$args{name} = $_;
# add AI task
AI::queue("leavemealone", \%args);
}
} else {
$blacklist_pos = 0;
}
$mustBlock = 0;
}
}
sub AI_hook {
if (AI_MODE) {
if (AI::action eq "leavemealone") {
return 0 unless (defined AI::args->{name});
if (Time::HiRes::time >= ($lastblocktime + BLOCKDELAY)) {
$lastblocktime = Time::HiRes::time;
msg("[".PLUGINNAME."] Player ".AI::args->{name}." has been blocked.\n");
Commands::run("ignore 1 ".AI::args->{name});
AI::dequeue;
}
}
} else {
unless ($::net->getState() == 5) {
$blacklist_pos = 0;
return;
}
if ($blacklist_pos < @blacklist) {
if (Time::HiRes::time >= ($lastblocktime + BLOCKDELAY)) {
$lastblocktime = Time::HiRes::time;
msg("[".PLUGINNAME."] Player ".$blacklist[$blacklist_pos]." has been blocked.\n");
Commands::run("ignore 1 ".$blacklist[$blacklist_pos]);
$blacklist_pos++;
}
}
}
}
# used this for a while: unlike openkore's default AI::queue, this sub adds actions at lowest priority.
# someday it should be useful, so we're keeping it
# sub ai_queue_low_priority {
# push @AI::ai_seq, shift;
# my $args = shift;
# push @AI::ai_seq_args, ((defined $args) ? $args : {});
# }
sub messages {
return unless(DISABLESPAMCHECKS ne 1);
my (undef, $args) = @_;
my $charname;
my $actor;
if (defined $args->{pubMsgUser}) {
$charname = $args->{pubMsgUser};
$actor = Actor::get($args->{pubID});
if ($actor->{guild}{name} ne '' && SPAMONLYGUILDLESS eq 1) { return; }
} elsif (defined $args->{privMsgUser}) {
$charname = $args->{privMsgUser};
}
lastAccessVerify(2);
if (@whitelist) {
foreach (@whitelist) {
if ($charname eq $_) {
msg("[".PLUGINNAME."] Player ".$charname." is whitelisted, we won't check him.\n", undef, 1);
return;
}
}
}
if (($userlist{$charname}{'lastPMtime'} - $userlist{$charname}{'time'}) > RESETCOUNT) { delete $userlist{$charname}; };
#delete $userlist{$charname};
if (!$userlist{$charname}{'pmcount'}) {
$userlist{$charname}{'time'} = time - 1;
}
$userlist{$charname}{'pmcount'}++;
$userlist{$charname}{'lastPMtime'} = time;
my $pmpersecond = $userlist{$charname}{'pmcount'}/(time - $userlist{$charname}{'time'});
if ($pmpersecond > MAXPMPERSECOND && $userlist{$charname}{'pmcount'} > MINPMCOUNT) {
msg("[".PLUGINNAME."] Blocking ".$charname." for spamming.\n");
comm_Black(undef, $charname);
}
msg(
"[".PLUGINNAME."] Player : ".$charname."\n Guild : ".$actor->{guild}{name}."\n Level : ".$actor->{lv}."\n".
" PM Per Second : ".$pmpersecond."\n PMs Received : ".$userlist{$charname}{'pmcount'}."\n"
,undef,1
);
}
sub comm_White {
my (undef, $argument) = @_;
if ($argument eq '' || $argument eq '?' || $argument eq 'help') {
msg ("[".PLUGINNAME."] Syntax Error in function 'whitelist'\n".
"[".PLUGINNAME."] Usage: \n\n".
"[".PLUGINNAME."] Add player : whitelist <username>\n".
"[".PLUGINNAME."] Remove player : whitelist rem <username>\n".
"[".PLUGINNAME."] Clear whitelist.txt : whitelist clear\n".
"[".PLUGINNAME."] Print whitelist content : whitelist print\n".
"[".PLUGINNAME."] Syntax help : whitelist ?, whitelist help\n"
, 3); return 0;
} elsif ($argument eq 'print') {
warning("[whitelist.txt]\n\n");
foreach (@whitelist) {
warning($_."\n");
}
return 1;
} elsif ($argument eq 'clear') {
@whitelist = undef;
open WHITELIST, ">:utf8", $workingFolder."/leaveMeAlone/whitelist.txt"
or die "cannot open ".$workingFolder."/leaveMeAlone/whitelist.txt: $!";
close WHITELIST;
$lastAccess{whitelist}{lastSize} = -s $lastAccess{whitelist}{path};
return 1;
} elsif ($argument =~ /^rem (.*)|^rem$/) {
$argument = $1;
if ($argument eq '') { msg("[".PLUGINNAME."] Syntax Error in function 'whitelist rem'\n[".PLUGINNAME."] Usage: block <username>\n", 3); return; }
# search for <username> to remove, throw an error if not found
unless (isInlist(2, $argument)) { msg("[".PLUGINNAME."] ".$argument." not found in whitelist.\n", 3); return; }
my @temp = @whitelist;
@whitelist = undef;
foreach (@temp) {
push (@whitelist, $_) unless ($_ eq $argument || $_ eq "");
}
open WHITELIST, ">:utf8", $workingFolder."/leaveMeAlone/whitelist.txt"
or die "cannot open ".$workingFolder."/leaveMeAlone/whitelist.txt: $!";
foreach (@whitelist) {
print WHITELIST $_."\n";
}
close WHITELIST;
msg("[".PLUGINNAME."] Player ".$argument." has been removed from whitelist.\n");
$lastAccess{whitelist}{lastSize} = -s $lastAccess{whitelist}{path};
return 1;
} else {
unless (!isInlist(1, $argument)) {
error("[".PLUGINNAME."] ".$argument." is already in whitelist.\n");
return;
}
unless (!isInlist(2, $argument)) {
error("[".PLUGINNAME."] ".$argument." is already in blacklist. Use \"blacklist rm <username>\" to remove him first.\n");
return;
}
# add to array
push (@whitelist, $argument);
open WHITELIST, ">:utf8", $workingFolder."/leaveMeAlone/whitelist.txt"
or die "cannot open ".$workingFolder."/leaveMeAlone/whitelist.txt: $!";
foreach (@whitelist) {
print WHITELIST $_."\n";
}
close WHITELIST;
msg("[".PLUGINNAME."] Player ".$argument." has been added to whitelist.\n");
$lastAccess{whitelist}{lastSize} = -s $lastAccess{whitelist}{path};
return 1;
}
}
sub comm_Black {
my (undef, $argument) = @_;
if ($argument eq '' || $argument eq '?' || $argument eq 'help') {
msg ("[".PLUGINNAME."] Syntax Error in function 'blacklist'\n".
"[".PLUGINNAME."] Usage: \n\n".
"[".PLUGINNAME."] Add and block player : blacklist <username>\n".
"[".PLUGINNAME."] Remove player : blacklist rem <username>\n".
"[".PLUGINNAME."] Clear blacklist.txt : blacklist clear\n".
"[".PLUGINNAME."] Print blacklist content : blacklist print\n".
"[".PLUGINNAME."] Syntax help : blacklist ?, blacklist help\n"
, 3); return 0;
} elsif ($argument eq 'print') {
warning("[blacklist.txt]\n\n");
foreach (@blacklist) {
warning($_."\n");
}
return 1;
} elsif ($argument eq 'clear') {
@blacklist = undef;
open BLACKLIST, ">:utf8", $workingFolder."/leaveMeAlone/blacklist.txt"
or die "cannot open ".$workingFolder."/leaveMeAlone/blacklist.txt: $!";
close BLACKLIST;
$lastAccess{blacklist}{lastSize} = -s $lastAccess{blacklist}{path};
return 1;
} elsif ($argument =~ /^rem (.*)|^rem$/) {
$argument = $1;
# search for <username> to remove, throw an error if not found
unless (isInlist(1, $argument)) { msg("[".PLUGINNAME."] ".$argument." not found in blacklist.\n", 3); return; }
my @temp = @blacklist;
@blacklist = undef;
foreach (@temp) {
push (@blacklist, $_) unless ($_ eq $argument || $_ eq "");
}
open BLACKLIST, ">:utf8", $workingFolder."/leaveMeAlone/blacklist.txt"
or die "cannot open ".$workingFolder."/leaveMeAlone/blacklist: $!";
foreach (@blacklist) {
print BLACKLIST $_."\n";
}
close BLACKLIST;
Commands::run("ignore 0 ".$argument);
msg("[".PLUGINNAME."] Player ".$argument." has been unblocked and removed from blacklist.\n");
$lastAccess{blacklist}{lastSize} = -s $lastAccess{blacklist}{path};
return 1;
} else {
unless (!isInlist(1, $argument)) {
error("[".PLUGINNAME."] ".$argument." is already in whitelist. Use \"whitelist rm <username>\" to remove him first.\n");
return;
}
unless (!isInlist(2, $argument)) {
error("[".PLUGINNAME."] ".$argument." is already in blacklist.\n");
return;
}
# add to array
push (@blacklist, $argument);
open BLACKLIST, ">:utf8", $workingFolder."/leaveMeAlone/blacklist.txt"
or die "cannot open ".$workingFolder."/leaveMeAlone/blacklist.txt: $!";
foreach (@blacklist) {
print BLACKLIST $_."\n";
}
close BLACKLIST;
Commands::run("ignore 1 ".$argument);
msg("[".PLUGINNAME."] Player ".$argument." has been blocked and added to blacklist.\n");
$lastAccess{blacklist}{lastSize} = -s $lastAccess{blacklist}{path};
return 1;
}
}
sub msg {
# SILENT constant support and sprintf.
my ($msg, $msglevel, $debug) = @_;
unless ($debug eq 1 && DEBUG ne 1) {
if (!defined $msglevel || $msglevel == "" || $msglevel == 0) {
warning($msg) unless (SILENT == 1);
} elsif ($msglevel == 1) {
message($msg) unless (SILENT == 1);
} elsif ($msglevel == 2) {
warning($msg) unless (SILENT == 1);
} elsif ($msglevel == 3) {
error($msg);
}
}
return 1;
}
sub isInlist {
my ($list, $name) = @_;
&lastAccessVerify($list);
if ($list == 1) {
foreach (@whitelist) {
if ($name eq $_) {
msg("[".PLUGINNAME."] ".$name." found in whitelist !.\n", undef, 1);
return 1;
}
}
return 0;
} elsif ($list == 2) {
foreach (@blacklist) {
if ($name eq $_) {
msg("[".PLUGINNAME."] ".$name." found in black !.\n", undef, 1);
return 1;
}
}
return 0;
} else {
msg("[".PLUGINNAME."] Error in isInlist() while accessing list ".$list.", please report this\n", 3);
}
}
sub lastAccessVerify {
my $arg = shift;
# 1 for blacklist, 2 for whitelist
if ($arg == 1 && ((-s $lastAccess{blacklist}{path}) ne $lastAccess{blacklist}{lastSize})) {
msg("[".PLUGINNAME."] blacklist changed, reloading.\n", 3, 1);
&load_blacklist;
return 1;
} elsif ($arg == 2 && ((-s $lastAccess{whitelist}{path}) ne $lastAccess{whitelist}{lastSize})) {
msg("[".PLUGINNAME."] whitelist changed, reloading.\n", 3, 1);
&load_whitelist;
return 1;
} elsif ($arg ne 1 && $arg ne 2) {
msg("[".PLUGINNAME."] Error in lastAccessVerify() while accessing ".$arg.", please report this\n", 3);
die;
}
msg("[".PLUGINNAME."] .txt files are okay, same size as before.\n", 3, 1);
}
######################################
######## KEPT FOR COMPATIBILITY
sub comm_Block {
my (undef, $argument) = @_;
comm_Black(undef, $argument);
return 1;
}
sub comm_Unblock {
my (undef, $argument) = @_;
comm_Black(undef, "rem ".$argument);
return 1;
}
1;
# i luv u mom