PDA

View Full Version : Code: Player Flags (Perl and Command)


Cisyouc
10-28-2004, 11:16 AM
Hello all.
For awhile now I've been meaning to finish this command to restrict access to zones if you dont have a certain flag. After alot of reworks Ive got a working version.

It works very simply. Here is the schema:
DROP TABLE IF EXISTS qflags;
CREATE TABLE qflags (
charid varchar(64) NOT NULL,
zoneid int(11) NOT NULL default 0,
UNIQUE KEY qflag (charid,zoneid)
) TYPE=MyISAM;

alter table zone add qflagreq int(2) NOT NULL default '0';

Below is the code, and below that will be the syntax for #qflag and quest::qflag();. How the code works is it checks qflagreq to see if the zone requires the client to have a flag to enter. If it is 0, it skips the qflag code. If it is 1, it will require a flag. It will then look up the user in the qflag table for that specific zone id. If the flag doesnt exist, the user will not be able to enter. If they do have a flag, the zone will process the user and send them off normally.

Database.cpp
FIND: cerr << "Error in GetLiveChar query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}

return false;
}ADD AFTER:
//Cisyouc: Begin qFlag Checks
bool Database::ControlqFlag(const char* name, uint32 zoneid, bool adding)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;

if(adding == TRUE)
{
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO qflags (charid, zoneid) VALUES ('%s','%i');",name,zoneid), errbuf))
{
safe_delete_array(query)
return false;
}
else
{
safe_delete_array(query)
return true;
}
}
if(adding == FALSE)
{
if(!RunQuery(query, MakeAnyLenString(&query, "DELETE FROM qflags WHERE charid='%s' AND zoneid=%i;", name, zoneid), errbuf))
{
safe_delete_array(query)
return false;
}
else
{
safe_delete_array(query)
return true;
}
}
return false;
}
bool Database::GetqFlag(const char* name, uint32 zoneid)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if(!RunQuery(query, MakeAnyLenString(&query, "SELECT zoneid FROM qflags WHERE charid='%s' AND zoneid=%i;",name,zoneid), errbuf, &result))
{
cerr << "[qFlag] Error connecting to db." << endl;
return false;
}
else
{
row=mysql_fetch_row(result);
if(mysql_num_rows(result) >= 1)
{
if(atoi(row[0]) == zoneid)
{
return true;
}
else
{
return false;
}
}
else if(mysql_num_rows(result) == 0)
{
return false;
}
cerr << "[qFlag] An error has occured." << endl;
return false;
}
return false;
}

bool Database::GetNeedqFlag(uint32 zoneid)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if(!RunQuery(query, MakeAnyLenString(&query, "SELECT qflagreq FROM zone WHERE zoneidnumber=%i;",zoneid), errbuf, &result))
{
cerr <<"[qFlag] Error Checking qFlag: " << errbuf << endl;
return FALSE;
}
else
{
row=mysql_fetch_row(result);
if(atoi(row[0]) == 1)
{
mysql_free_result(result);
return TRUE;

}
else
{
mysql_free_result(result);
return FALSE;
}
mysql_free_result(result);
return FALSE;
}
return FALSE;
}
//Cisyouc: End qFlag Checks

Database.h
FIND: bool UpdateLiveChar(char* charname,int32 lsaccount_id);
ADD AFTER: bool ControlqFlag(const char* name, uint32 zoneid, bool adding = true);
bool GetqFlag(const char* name, uint32 zoneid);
bool GetNeedqFlag(uint32 zoneid);
client_process.cpp
FIND:#ifdef RAIDADDICTS
if (!raidaddicts.ZoneInCheck(zc->zoneID, this)) {
myerror = ZONE_ERROR_NOEXPERIENCE;
RAZone = false;
}
#endif
ADD AFTER: //Cisyouc: Begin qFlag Additions
if(database.GetNeedqFlag(zc->zoneID))
{
cerr << "[qFlag] Loading qFlags for zone: " << zc->zoneID << endl;
if(!database.GetqFlag(GetName(),zc->zoneID))
{
cout << "[qFlag] User " << GetName() << " denied entry." << endl;
strcpy(target_zone,zone->GetShortName());
tarx = GetX();
tary = GetY();
tarz = GetZ();
zonesummon_x = 0;
zonesummon_y = 0;
zonesummon_z = 0;
Message(15, "Your will is not sufficient to pass into this area.");
}
else
{
cout << "[qFlag] " << GetName() << " has appropriate qflag for zone "<< zc->zoneID << endl;
}
}
//Cisyouc: End qFlag Additions


command.cpp
FIND: command_add("pf","- ",0,command_pf) ||
ADD AFTER: //Cisyouc: qflag implementation
command_add("qflag","[add/delete/help(1,2,3)] [name] [zoneid]",80,command_qflag) ||

FIND: cd->unknown15[0] = sep->arg[4][0] ? atoi(sep->arg[4]) : 0;
cd->unknown15[1] = sep->arg[5][0] ? atoi(sep->arg[5]) : 0;
cd->unknown19 = sep->arg[6][0] ? atoi(sep->arg[6]) : 0;
entity_list.QueueClients(c, outapp);
safe_delete(outapp);
*/
}
ADD AFTER: //Cisyouc: Begin qFlag Implementation
void command_qflag(Client *c, const Seperator *sep)
{
if(atoi(sep->arg[1]) == 2)
{
bool result = database.ControlqFlag(sep->arg[2], atoi(sep->arg[3]), TRUE);
if(result == false)
{
c->Message(13, "An error has occured inserting into database.");
}
else if(result = true)
{
if(sep->arg[1] == c->GetName())
{
c->Message(15, "You have recieved a character flag!");
}
else
{
c->Message(15, "Player recieves a character flag!");
}
}
else
{
c->Message(13, "An unknown error has occured.");
}
}
if(atoi(sep->arg[1]) == 3)
{
bool result = database.ControlqFlag(sep->arg[2], atoi(sep->arg[3]), FALSE);
if(result == false)
{
c->Message(13, "An error has ocured inserting into database.");
}
else if(result = true)
{
if(sep->arg[1] == c->GetName())
{
c->Message(13, "You have had a character flag REVOKED!");
}
else
{
c->Message(13, "Player has had a character flag REVOKED!");
}
}
else
{
c->Message(13, "An unknown error has occured.");
}
}
if(atoi(sep->arg[1]) == 1)
{
if(atoi(sep->arg[2]) == 1)
{
c->Message(0, "To implement qFlag in quests, please use the PERL function,");
c->Message(0, "quest::qflag([function], [zoneid]);");
c->Message(0, "Functions: 1 = Add Flag, 2 = Delete Flag");
c->Message(0, "Example: quest::qflag(1,202);");
c->Message(0, "Flags user for poknowledge (202)");
}
else if(atoi(sep->arg[2]) == 2)
{
c->Message(0, "#qflag syntax:");
c->Message(0, "#qflag [function] [charname] [zoneid]");
c->Message(0, "Functions: 2 for ADD flag, 3 for DELETE flag.");
}
else
{
c->Message(0, "---Quest Flags by Cisyouc---");
c->Message(0, "Help file syntax:");
c->Message(0, "Quest Help: #qflag 1 1");
c->Message(0, "Command Help: #qflag 1 2");
}
}
}
//Cisyouc: End qFlag Implementation
command.h
FIND: void command_zcolor(Client *c, const Seperator *sep);
ADD AFTER: //Cisyouc qflag command
void command_qflag(Client *c, const Seperator *sep);

FOR PERL IMPLEMENTATION:
embparser.cpp
"sub qflag{push(@cmd_queue,{func=>'qflag',args=>join(',',@_)});}"

parser.cpp
else if (!strcmp(command,"qflag")) {
/*
qFlag Implementation for Perl
By Cisyouc
Syntax: quest::qflag([function],[zoneid])
Functions:
1 for FLAG
2 for REMOVE FLAG
See example on EQEmulator.net
Be sure to source necessary sql file before use.
*/

char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;

if(atoi(arglist[0]) == 1)
{
if(!database.RunQuery(query, MakeAnyLenString(&query, "INSERT INTO qflags (charid, zoneid) VALUES ('%s','%s');",mob->CastToClient()->GetName(), arglist[1]), errbuf, &result))
{
cout << "[qFlag] Quest::qFlag Ran: " << mob->CastToClient()->GetName() << " has been flagged for " << atoi(arglist[1]) << endl;
mob->Message(15, "You have recieved a character flag!");
}

else
{
cout << "[qFlag] Could not flag " << mob->CastToClient()->GetName() << " for " << atoi(arglist[1]) << "." << endl;
cout << "[qFlag] Database Error: " << errbuf << endl;
mob->Message(13, "An error has occured. Please contact a GM as soon as possible.");
}
mysql_free_result(result);
}
else if(atoi(arglist[0]) == 2)
{
if(!database.RunQuery(query, MakeAnyLenString(&query, "DELETE FROM qflags WHERE charid='%s' AND zoneid=%s;",mob->CastToClient()->GetName(), arglist[1]), errbuf, &result))
{
cout << "[qFlag] Quest::qFlag Ran: " << mob->CastToClient()->GetName() << " has had flag REVOKED for " << atoi(arglist[1]) << endl;
mob->Message(13, "You have had a character flag REVOKED!");
}

else
{
cout << "[qFlag] Could not flag " << mob->CastToClient()->GetName() << " for " << atoi(arglist[1]) << "." << endl;
cout << "[qFlag] Database Error: " << errbuf << endl;
mob->Message(13, "An error has occured. Please contact a GM as soon as possible.");
}
mysql_free_result(result);
}
}


Syntax:
Help: #qFlag 1 help
Help w/Quests: #qFlag 1 1
Help w/Commands: #qFlag 1 2
Flag Player: #qFlag 2 [charname] [zoneid]
De-Flag Player: #qFlag 3 [charname] [zoneid]

Perl Syntax:
Add Flag: quest::qflag(1, [zoneid]);
De-Flag: quest::qflag(2, [zoneid]);

So, again, to make a zone require a flag, do this mysql query:
UPDATE zone SET qflagreq='1' WHERE zoneidnumber='xxxx';
(Replacing xxx with the zone id)

Thanks to the guys at #perl for catching my stupid mistakes :D

Let me know what you think of this.

Scorpx725
10-28-2004, 11:31 AM
Very nice job, Cisyouc, glad I could help today.

RangerDown
10-28-2004, 11:32 AM
Double check the primary key on your schema.

Under that schema, a character can be flagged for only one zone at a time.

Cisyouc
10-28-2004, 11:36 AM
Double check the primary key on your schema.

Under that schema, a character can be flagged for only one zone at a time.Whoops. Fixed.

Cisyouc
10-28-2004, 02:12 PM
Bah. Also fixed a syntax error too, I just spotted.

eq_addict_08
10-28-2004, 07:14 PM
Yea!! Will merge into my server asap. Man, I realy need to learn how to progam, would love to contribute something worthwhile.

ajb20
10-29-2004, 02:08 AM
c:\documents and settings\adamxp\desktop\eqemucvs\source\common\dat abase.cpp(1170) : warning C4715: 'Database::GetqFlag' : not all control paths return a value



command.cpp(865) : warning C4805: '==' : unsafe mix of type 'char' and type 'bool' in operation
command.cpp(888) : warning C4805: '==' : unsafe mix of type 'char' and type 'bool' in operation


Other than that compiled great. Thanks Cisyouc. For those of you without a compiler, I added it here http://www.eqemulator.net/forums/viewtopic.php?t=17924

Cisyouc
10-29-2004, 06:41 AM
Hmmm. I'm not getting those warnings, ajb. Regardless as long as #qFlag works its not worth worrying about =)

cofruben
10-29-2004, 06:46 AM
nice work Cisyouc.Still helping :).

m0oni9
10-29-2004, 07:42 AM
Hmmm. I'm not getting those warnings, ajb. Regardless as long as #qFlag works its not worth worrying about =)
Not to be a pedant, but it is good practice to fix warnings. Just because it works now does not guarantee it will work later on, or in another situation (ie: for someone else).

Cisyouc
10-29-2004, 07:57 AM
Hmmm. I'm not getting those warnings, ajb. Regardless as long as #qFlag works its not worth worrying about =)
Not to be a pedant, but it is good practice to fix warnings. Just because it works now does not guarantee it will work later on, or in another situation (ie: for someone else).My lazyness at best.

-edit-
Syntax fixed.