Limit Players/Items in Zone by IP
I have a custom pvp zone. The pvp code I can post later, but if anyone wants, here is the code that will limit 1 player per IP in the zone. I also check to see if the player has certain items, flags, or level, in order to boot them from the zone since its specifically a level 60 only pvp zone with no twink items allowed. The check for flags, items, and level can easily be removed, and just use a stripped down version to limit by IP address only.
The ONLY plugin required would be check_hasitem which we should all have anyways from default plugin list.
The REFRESH_LIST_OF_PLAYERS() in timer is currently commented out and not required, but can uncomment it and the list of player IP would get refreshed once an hour, in case any problems with corrupt list, would make a new list. Was created to resolve a previous issue that is also now resolved, from players getting locked out, no longer get locked out now when trying to zone in 2 characters. You'll still be able to get 1 character in.
Code:
# \quests\commons\player.pl
#Declares and dependencies
use List::Util qw(first);
@ClientIP;
@ClientName;
@ClientList;
# Custom Crafted Armor Not Allowed!
@ItemList = qw(
113301
113302
113303
113304
113305
113306
113307
113311
113312
113313
113314
113315
113316
113317
113321
113322
113323
113324
113325
113326
113327
113331
113332
113333
113334
113335
113336
113337
113341
113342
113343
113344
113345
113346
113347
113351
113352
113353
113354
113355
113356
113357
113361
113362
113363
113364
113365
113366
113367
);
sub EVENT_SAY
{
if ($text=~/^#TARGET$/i && $status > 0) { EVENT_TARGET_CHANGE(); }
if ($text=~/^#LIST$/i && $status > 0) { LIST_WHO_IS_HERE(); }
if ($text=~/^#ENTER$/i && $status > 0) { EVENT_ENTERZONE(); }
if ($text=~/^#REFRESH$/i && $status > 0) { REFRESH_LIST_OF_PLAYERS(); }
if ($text=~/^#REMOVE LIST$/i && $status > 0) { REMOVE_FROM_LIST(); }
return 1;
}
sub EVENT_ENTERZONE
{
REMOVE_FROM_LIST(); # <--- DO THIS FIRST!!
my $CIP = GET_REAL_IP($name);
# IF IP IS ON THE LIST, THEN BOOT THEM!
if (grep {$_ eq $CIP} @ClientIP)
{
# IF NOT GM THEN ZONE THEM OUT
if ($status < 100)
{
$client->Message(13, "You already have a character from same IP in this zone!");
quest::movepc(152,0,0,-30,0);
}
# ELSE GM, SO ALLOW THEM TO STAY BUT ADD THEM TO LIST
else
{
quest::gmsay("$name: EVENT_ENTERZONE: Already in Zone but your a GM!", 18, 0);
ADD_TO_LIST();
}
}
# Prevent any further checks if your a GM, and add to list too
elsif ($status > 100)
{
quest::gmsay("$name: EVENT_ENTERZONE: NO MORE CHECKS FOR BANNED ITEMS CAUSE YOUR A GM!", 18, 0);
ADD_TO_LIST();
}
elsif ($ulevel > 60)
{
$client->Message(15, " ");
$client->Message(15, "You can not be over level 60 for this zone.");
quest::movepc(152,0,0,-28); # Zone Nexus
}
elsif(defined($qglobals{casterlevel}) && $qglobals{casterlevel} > 0 || quest::istaskcompleted(602))
{
$client->Message(15, " ");
$client->Message(15, "You can not have a Caster Guild flag for this zone.");
quest::movepc(152,0,0,-28); # Zone Nexus
}
elsif(defined($qglobals{fighterlevel}) && $qglobals{fighterlevel} > 0 || quest::istaskcompleted(601))
{
$client->Message(15, " ");
$client->Message(15, "You can not have a Fighters Guild flag for this zone.");
quest::movepc(152,0,0,-28); # Zone Nexus
}
elsif(defined($qglobals{crafterlevel}) && $qglobals{crafterlevel} > 0)
{
$client->Message(15, " ");
$client->Message(15, "You can not have a Crafters Guild flag for this zone.");
quest::movepc(152,0,0,-28); # Zone Nexus
}
elsif(defined($qglobals{qviclevel}) && $qglobals{qviclevel} > 0 || quest::istaskcompleted(603))
{
$client->Message(15, " ");
$client->Message(15, "You can not have an Epic 3.0 flag for this zone.");
quest::movepc(152,0,0,-28); # Zone Nexus
}
elsif(defined($qglobals{poglevel}) && $qglobals{poglevel} > 0)
{
$client->Message(15, " ");
$client->Message(15, "You can not have a Plane of Gods flag for this zone.");
quest::movepc(152,0,0,-28); # Zone Nexus
}
# ELSE IP NOT ON LIST YET, AND NO REASON TO BAN, SO ADD IP and NAME
else
{
ADD_TO_LIST();
}
EVENT_TARGET_CHANGE(); # Made by Hunter, check for banned items when changing targets
quest::settimer("CUSTOM_ITEMS_TIMER",60); # Check for banned items every 60 Seconds
quest::settimer("REFRESH_PVP_LIST",30); # REFRESH IP/NAME LIST IN 30 SECONDS, THEN WILL SET TO REFRESH ONCE AN HOUR!
} # End EVENT_ENTERZONE
# GM LIST OF PLAYERS IN ZONE
sub LIST_WHO_IS_HERE
{
if ($status > 100) { quest::gmsay(" ", 18, 0); }
if ($status > 100) { quest::gmsay("GM: LIST_WHO_IS_HERE()", 18, 0); }
my $i = 0;
while ($ClientIP[$i])
{
if ($status > 100) { quest::gmsay("GM: $ClientIP[$i] <> $ClientName[$i]", 18, 0); }
$i++;
}
}
# catchs when client zones
sub EVENT_ZONE
{
REMOVE_FROM_LIST();
}
# Catchs hard disconnect only, /q LD CTD
sub EVENT_DISCONNECT
{
REMOVE_FROM_LIST();
}
sub ADD_TO_LIST
{
my $CIP2 = GET_REAL_IP($name);
push(@ClientIP, $CIP2);
push(@ClientName, $name);
$client->Message(7, "$name, your IP has been added to a list.");
return 1;
}
# Remove both Player IP and Player Name from list
sub REMOVE_FROM_LIST
{
if ($status > 100) { quest::gmsay(" ", 18, 0); }
if ($status > 100) { quest::gmsay("GM: REMOVE_FROM_LIST()", 18, 0); }
my $index = 0;
while ($ClientName[$index])
{
if ($ClientName[$index] eq $name)
{
# GM SAY MUST GO BEFORE SPLICE!
quest::gmsay("REMOVED: $ClientIP[$index] <> $ClientName[$index]", 18, 0);
splice(@ClientIP, $index, 1);
splice(@ClientName, $index, 1);
}
$index++;
}
}
# Timer goes off 60s after someone enters zone.
sub EVENT_TIMER
{
if ($timer eq "CUSTOM_ITEMS_TIMER")
{
EVENT_TARGET_CHANGE();
}
if ($timer eq "REFRESH_PVP_LIST")
{
# REFRESH_LIST_OF_PLAYERS(); # Now safe to enable
quest::stoptimer("REFRESH_PVP_LIST");
quest::settimer("REFRESH_PVP_LIST",3600); # REFRESH LIST ONCE AN HOUR!
}
}
sub REFRESH_LIST_OF_PLAYERS
{
if ($status > 100) { quest::gmsay(" ", 18, 0); }
if ($status > 100) { quest::gmsay("REFRESH_LIST_OF_PLAYERS", 18, 0); }
undef(@ClientIP);
undef(@ClientName);
my @ClientList = $entity_list->GetClientList();
foreach $ent (@ClientList)
{
my $GET_IP = GET_REAL_IP($ent->GetName()); # Don't use $name or else everyone's IP will be the same!
my $GET_NAME = $ent->GetName();
push(@ClientIP, "$GET_IP");
push(@ClientName, "$GET_NAME");
quest::gmsay("Refresh: $GET_IP <> $GET_NAME", 18, 0);
}
return 1;
}
sub GET_REAL_IP
{
my $connect = LoadMySQLConnection();
my $FIND_TOON_NAME = $_[0];
my $GET_IP = 0;
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";
my $query_handle = $connect->prepare($query);
$query_handle->execute();
if ($query_handle->rows)
{
my $ref = $query_handle->fetchrow_hashref();
$GET_IP = $ref->{'ip'};
}
$query_handle->finish();
$connect->disconnect();
return $GET_IP;
} # End GET_REAL_IP()
sub LoadMySQLConnection
{
use DBI;
use DBD::mysql;
my $confile = "eqemu_config.xml"; #default config file
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()
# CHECK IF PLAYER HAS BANNED ARMOR AND ZONE OUT IF PLAYER HAS
sub EVENT_TARGET_CHANGE
{
if ($status > 0) { quest::gmsay("EVENT_TARGET_CHANGE", 18, 0); }
my $GET_CUSTOM_ARMOR = FIND_CUSTOM_ARMOR();
if ($GET_CUSTOM_ARMOR)
{
if ($status > 100)
{
quest::gmsay("GM: HAS CUSTOM ARMOR = YES", 18, 0);
quest::gmsay("GM: Not movepc cause your GM!", 18, 0); # GM DONT MOVE
}
else
{
# Remove player IP and Name from list before kicking them out of the zone
REMOVE_FROM_LIST(); # Do this before zoning out
quest::movepc(152,0,0,-30,0); # IF NOT GM THEN ZONE THEM OUT
}
}
else
{
if ($status > 0) { quest::gmsay("GM: HAS CUSTOM ARMOR = NO", 18, 0); }
else { } # DO NOTHING
}
quest::stoptimer("CUSTOM_ITEMS_TIMER");
quest::settimer("CUSTOM_ITEMS_TIMER",60); # CHECK FOR BANNED ITEMS EVERY 1 MINUTE
}
sub FIND_CUSTOM_ARMOR
{
my $n = 0;
while ($ItemList[$n])
{
my $itemz = int($ItemList[$n]);
if(plugin::check_hasitem($client, $itemz))
{
$client->Message(15, "You have custom armor.");
return 1;
}
$n++;
}
return 0;
}
|