Server Guild AutoJoin

EQ2Emulator Development forum.

Moderator: Team Members

Post Reply
User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Server Guild AutoJoin

Post by John Adams » Fri Jul 29, 2011 7:30 am

Scat, I'm going to need your help on this one. Just a little bonus feature, because I needed it for the EQ2TC, I added some code that when a new player is created, they are automatically joined to a specific Guild ID on my server.

I totally hacked this in with a machete though, so I would like you to please look this code over and bless it, or show me how to do it right.

WorldDatabase.cpp

Code: Select all

WorldDatabase::AddNewPlayerToServerGuild(int32 char_id)
As all the new player data is being saved on Create, this function is now called to check the Rules to put the player in the Guild ID of your choice, at the Rank of your choice.

I could not seem to access the normal AddNewGuildMember-type functions, because I think they are for in-game invite only. I need a way to invite a player without their consent.


Which brings me to request #2 :)

Add a GM command to forcibly add/remove players from guilds without the player needing to be online or Accepting the invite. If my code above is "proper", I can invent the COMMAND itself, once I see how you do it.

Thanks

User avatar
Scatman
Retired
Posts: 1688
Joined: Wed Apr 16, 2008 5:44 am
EQ2Emu Server: Scatman's Word
Characters: Scatman
Location: New Jersey

Re: Server Guild AutoJoin

Post by Scatman » Mon Aug 01, 2011 5:07 pm

This function will only be called before the player actually gets in game, right?

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Re: Server Guild AutoJoin

Post by John Adams » Mon Aug 01, 2011 6:24 pm

Yes, only on character create, after most of the player stats have been written on creation, before actually hitting the ground.

I tossed a reload guilds in there, but I am 100% certain that hack will come back to haunt me. Seems to work so far, but I'm sure you have a better idea ;)

User avatar
Scatman
Retired
Posts: 1688
Joined: Wed Apr 16, 2008 5:44 am
EQ2Emu Server: Scatman's Word
Characters: Scatman
Location: New Jersey

Re: Server Guild AutoJoin

Post by Scatman » Mon Aug 01, 2011 7:17 pm

Nope that is actually just fine. You don't need to send any packets because world will pick up the player when they log in. Just rewrite the query into its own function so you can re-use it for the commands too.

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Re: Server Guild AutoJoin

Post by John Adams » Tue Aug 02, 2011 10:58 am

The thing I was worried about was that my code has no locking. What if a new char is being created while someone is joining a guild, etc... chances are probably small, but I'd had my code to cause more deadlocks.

I'll move the query to it's own function like you suggest. Thanks!

User avatar
Scatman
Retired
Posts: 1688
Joined: Wed Apr 16, 2008 5:44 am
EQ2Emu Server: Scatman's Word
Characters: Scatman
Location: New Jersey

Re: Server Guild AutoJoin

Post by Scatman » Tue Aug 02, 2011 4:24 pm

Nope no locking needed. The locking is handled by the guild functions. However, I would get rid of the reload all guilds. All you need to do is:

Build a GuildMember* struct using the fields that go into the database table for the new guildmember.
Then call Guild::AddGuildMember(GuildMemeber *gm);

Code: Select all

GuildMember *gm = new GuildMember;
gm->blah = blah;
gm->blah = blah;
Query to insert the guild member
guild->AddGuildMember(gm);

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Re: Server Guild AutoJoin

Post by John Adams » Tue Aug 02, 2011 4:37 pm

Scatman wrote:All you need to do is:

Build a GuildMember* struct using the fields that go into the database table for the new guildmember.
Then call Guild::AddGuildMember(GuildMemeber *gm);
What I heard:
"Blah blah, blahblahblah, blah blah blahblahblah! Blah();"

User avatar
Scatman
Retired
Posts: 1688
Joined: Wed Apr 16, 2008 5:44 am
EQ2Emu Server: Scatman's Word
Characters: Scatman
Location: New Jersey

Re: Server Guild AutoJoin

Post by Scatman » Tue Aug 02, 2011 7:53 pm

Code: Select all

bool WorldDatabase::AddNewPlayerToServerGuild(int32 char_id) {
    GuildMember *gm = new GuildMember;

    //query database here to get player info from char_id

    //now fill the gm struct with the data from mysql and such
    gm->account_id=atoul(row[0]);
    gm->character_id=char_id;
    ...
    ...
    gm->zone = string("");

    guild->AddGuildMember(gm);

    //query here to put guild member in guild_members table (already there).
    return true;
}
So no need to reload any guilds. Just tell the guild there's a new member. (A blank zone means the player is offline). Once they log in, the normal guild code will take care of the rest.

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Re: Server Guild AutoJoin

Post by John Adams » Wed Aug 03, 2011 10:37 am

k, here's what i got. How's this look?

Code: Select all

bool WorldDatabase::AddNewPlayerToServerGuild(int32 account_id, int32 char_id)
{
	// Check if this servers rule allow auto-joining Server guild
	int8 autojoin = rule_manager.GetGlobalRule(R_World, GuildAutoJoin)->GetInt8();
	if( autojoin )
	{
		// if so, what is the guild ID of the default server guild?
		int32 guild_id = rule_manager.GetGlobalRule(R_World, GuildAutoJoinID)->GetInt32();
		Guild* guild = 0;
		guild = guild_list.GetGuild(guild_id);
		if (!guild) 
		{
			// guild was not valid, abort!
			LogWrite(GUILD__ERROR, "Guilds", "Guild ID %u not found! Cannot autojoin members!", guild_id);
			return false;
		}
		else
		{
			// guild was found, so what default Rank to make the players? if not set, use 7 (recruit)
			int8 rank_id = rule_manager.GetGlobalRule(R_World, GuildAutoJoinDefaultRankID)->GetInt8();
			if(!rank_id)
				rank_id = 7;

			// assuming all is good, insert the new guild member here...
			GuildMember *gm = new GuildMember();

			gm->account_id = account_id;
			gm->character_id = char_id;
			char* name = GetCharacterName(gm->character_id);
			strncpy(gm->name, name, sizeof(gm->name));
			gm->join_date = Timer::GetUnixTimeStamp();
			gm->rank = rank_id;
			gm->zone = string("");
			gm->note = string("Auto-Join Server Guild");

			guild->AddGuildMember(gm);
			LogWrite(GUILD__DEBUG, "Guilds", "Auto-join player (%u) to server guild '%s' (%u) at rank %i. Reloading Guilds...", char_id, guild->GetName(), guild_id, rank_id);

			Query query;
			query.RunQuery2(Q_INSERT, "INSERT INTO `guild_members` (`guild_id`, `char_id`, `join_date`, `rank_id`, `note`) VALUES (%lu, %lu, %lu, %i, 'Auto-Join Server Guild')", 
				guild_id, char_id, gm->join_date, rank_id);

			// success!
			return true;
		}
	}
	// do not auto-join server guild
	return false;
}
Can't wait to get home to test this ;)

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Re: Server Guild AutoJoin

Post by John Adams » Wed Aug 03, 2011 5:12 pm

Ok, the code is in and tested, yet when the newly joined character enters the zone for the first time, I crash on the loading of the recruiter picture data.

I know this won't do you good without seeing my commit, but in case ;)

Code: Select all

>	EQ2World__Debug_x64.exe!Guild::SendGuildRecruiterInfo(Client * client, Player * player)  Line 2101 + 0x26 bytes	C++
 	EQ2World__Debug_x64.exe!Guild::GuildMemberLogin(Client * client, bool first_login)  Line 1949	C++
 	EQ2World__Debug_x64.exe!Client::SendCharInfo()  Line 526	C++
 	EQ2World__Debug_x64.exe!Client::HandlePacket(EQApplicationPacket * app)  Line 929	C++
 	EQ2World__Debug_x64.exe!Client::Process(bool zone_process)  Line 1670 + 0x12 bytes	C++
 	EQ2World__Debug_x64.exe!ZoneServer::ClientProcess()  Line 1906 + 0x1f bytes	C++
 	EQ2World__Debug_x64.exe!ZoneServer::Process()  Line 881	C++
 	EQ2World__Debug_x64.exe!ZoneLoop(void * tmp)  Line 3914 + 0xa bytes	C++
 	EQ2World__Debug_x64.exe!_callthreadstart()  Line 261	C
 	EQ2World__Debug_x64.exe!_threadstart(void * ptd)  Line 243	C
 	kernel32.dll!000000007783652d() 	
 	[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]	
 	ntdll.dll!0000000077acc521() 	
and

Code: Select all

gm->recruiter_picture_data = 0xcdcdcdcdcdcdcdcd <Bad Ptr>
Who gives a crap about the recruiter picture when I am a guild member? There isn't one even set...


AND if I reload that same character without doing anything else, he logs in just fine.

SCAT?!

User avatar
Scatman
Retired
Posts: 1688
Joined: Wed Apr 16, 2008 5:44 am
EQ2Emu Server: Scatman's Word
Characters: Scatman
Location: New Jersey

Re: Server Guild AutoJoin

Post by Scatman » Wed Aug 03, 2011 10:28 pm

Yeah I need to re-do the picture stuff. Can you ignore it for now?

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Re: Server Guild AutoJoin

Post by John Adams » Thu Aug 04, 2011 6:30 am

How do I "ignore" it? Comment the lines out?

User avatar
Scatman
Retired
Posts: 1688
Joined: Wed Apr 16, 2008 5:44 am
EQ2Emu Server: Scatman's Word
Characters: Scatman
Location: New Jersey

Re: Server Guild AutoJoin

Post by Scatman » Thu Aug 04, 2011 5:50 pm

Try just setting it to null. I can't look at the code right now but if null crashes it too, modify the send packet to check for null. I should have that check in there though, because some people don't have pictures.

Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests