Go Back   EQEmulator Home > EQEmulator Forums > Archives > Archive::Development > Archive::Development

Archive::Development Archive area for Development's posts that were moved here after an inactivity period of 90 days.

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #1  
Old 02-14-2004, 06:45 PM
vesuvias
Fire Beetle
 
Join Date: Feb 2004
Posts: 17
Default My first contribution... Here goes nothing...

Forgive me if I do something taboo, I have only been following this scene for a little over a week. Any way I dove head first into the code and decided to fix a few things that were bugging me (err.. yeah).

Any way here is what I did:

-Zone Bind Points (added some fields to start_zones and fixed an issue that would crash the client if you died to your bind point)
-Fixed an issue that was causing you character creation skin selections to be lost, now everyone doesn't have to look the same (Yeeaa!!)

Additions

-the start_zone table now has support for wildcarding on selection this means that DB developers don't have to put in (number of selections on map screen) *(number of races) *(number of classes)*(number of dieties) = number records in the database. putting a -1 in of these fields in the DB basically selects all of the combinations for that field. So if I only wanted to have 1 starting point for each class I would put -1 in the diety, choice and race coloumn for each record.

When specifying start_zones just remeber this SQL statement (its the one we use now to get start_zones):
Code:
SELECT x,y,z,zone_id,bind_id,bind_x,bind_y,bind_z FROM start_zones WHERE (player_choice=%i OR  player_choice=-1) and (player_class=%i OR player_class=-1) and (player_deity=%i OR player_deity=-1) and (player_race=%i OR player_race=-1) ORDER BY select_rank DESC
select_rank allows you to assign importance to the start_zone record basically the more specific the start_zone record (records with more -1 wildcards are less specific) the greater the select_rank should be. A good rule is to start at 50 and for every wildcard you use subtract 10 from this value.

This allows you to specify things like I want all characters to start in the nexus as a default. However I want all warriors to start in Halas. This would require 2 records in the DB, one for the nexus with -1 for race,choice,class and diety and a select rank of say 10. And one for the warriors that go to halas and it would have -1 for race, choice, and diety and a select_rank of say 20. If later you wanted to further specify where agnostic warriors go, you would just add one more record with a higher select_rank.

Zoneing Fixes

well after I added that code I realised that bound characters that die crash thier clients (never knew that since I was never bound before). So I decided to hunt that bug down. It turns out that this peice of code was the culperit
Code:
					if (zc->zoneID != 0 && dead)
					{
#ifdef GUILDWARS
					if(animation > 65 && admin<80 && CheckCheat()){
						if(cheater || cheatcount>0){
							Message(15,"Cheater log updated...yup your busted,its not nice to cheat.");
							char descript[50]={0};
							sprintf(descript,"%s: %i","Death zone cheat");
							database.logevents(this->AccountName(),this->AccountID(),admin,this->GetName(),"none","Death zone cheat",descript,15);
							if(cheater==false){
								worldserver.SendEmoteMessage(0,0,0,13,"<Cheater Locator> We have found a cheater.  %s (Acct: %s) was just caught hacking, please show them what we think of hackers...",this->GetName(),this->AccountName());
								cheater=true;
							}
							cheatcount=0;
						}
						else
							cheatcount++;
					}
#else
					break;
#endif
					}
This section executes in the OP_ZoneChange case under handlepacket in client_process.cpp. Any way basically if you died and the zone change packet specified a zone (other than 0) then you would break??? You got a zone change requrest why wouldn't you want to finish it? Anyway taking out the break fixed the issue it seems.

I also cleaned up the code a little in OP_ZoneChange so you wouldn't do wierd things like go to -3,-3,-3 when there was a perfectly acceptable safe_zone to go too.

Character skins

The last thing I decided to tackle was character skins and this was acutually the hardest thing of all to debug. First I corrected struct that recieved info from the client on character creation as there were a few guessed at spots inside that struct. I did this through numerous tedious trial and error chracter creations (Ie create a gnome a certian way, then create a second gnome the exact same way except this time change just his beard and analysis the data we get).

After I got the data for CharCreate_Struct ok, I moved onto trying to figure out why these character specific skin changes never got back to client. It turns out that CharacterSelect_Struct had about 60 bytes of unknown data. So I then went through a fairly painful process of trying to figure out what order the data went in on its way back. Fortunatly I was able to figure it out finally. It was challenging though. Hope everyone can benefit from some of my work at least a little .

Here are the diffs:

First SQL changes

Code:
ALTER TABLE start_zones ADD bind_x FLOAT DEFAULT "0" NOT NULL
ALTER TABLE start_zones ADD bind_y FLOAT DEFAULT "0" NOT NULL
ALTER TABLE start_zones ADD bind_z FLOAT DEFAULT "0" NOT NULL
ALTER TABLE start_zones ADD select_rank TINYINT UNSIGNED DEFAULT "50" NOT NULL
Now the database.cpp diff:
Code:
Index: database.cpp
===================================================================
RCS file: /cvsroot/eqemu/eqemu/eqemu/Source/common/database.cpp,v
retrieving revision 1.1.1.11
diff -r1.1.1.11 database.cpp
1164,1165c1164
< 				cs->gender[char_num]	= pp->gender;
< 				cs->face[char_num]		= pp->face;
---
> 				cs->gender[char_num]	= pp->gender;				
1167a1167,1174
> 				cs->face[char_num]		= pp->face;
> 				cs->haircolor[char_num] = pp->haircolor;
> 				cs->beardcolor[char_num]= pp->beardcolor;
> 				cs->eyecolor2[char_num] = pp->eyecolor2;
> 				cs->eyecolor1[char_num] = pp->eyecolor1;
> 				cs->hair[char_num]		= pp->hairstyle;
> 				cs->beard[char_num]		= pp->beard;
> 				
6551c6558
< 	cout<<"Choice:"<<in_cc->start_zone<<endl;
---
> 	//cout<<"Choice:"<<in_cc->start_zone<<" Class:"<<in_cc->class_<<" Race:"<<in_cc->race<<" Diety:"<<in_cc->deity<<endl;
6556c6563,6564
< if (RunQuery(query, MakeAnyLenString(&query, "SELECT x,y,z,zone_id,bind_id FROM start_zones WHERE player_choice=%i and player_class=%i and player_deity=%i and player_race=%i", in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race), errbuf, &result)) {         
---
> 	int qLen = MakeAnyLenString(&query, "SELECT x,y,z,zone_id,bind_id,bind_x,bind_y,bind_z FROM start_zones WHERE (player_choice=%i OR  player_choice=-1) and (player_class=%i OR player_class=-1) and (player_deity=%i OR player_deity=-1) and (player_race=%i OR player_race=-1) ORDER BY select_rank DESC", in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race);
> if (RunQuery(query,qLen,errbuf,&result)) {         
6564c6572,6597
<          in_pp->bind_zone_id = atoi(row[4]); 
---
>          in_pp->bind_zone_id = atoi(row[4]);
> 		 //if we haven't set a bind_zone_id lets set it to the starting zone
> 		 if (in_pp->bind_zone_id ==0) in_pp->bind_zone_id = in_pp->zone_id; 
> 		 in_pp->bind_x = atof(row[5]);
> 		 in_pp->bind_y = atof(row[6]);
> 		 in_pp->bind_z = atof(row[7]);
> 		 //if bind x,y,z are all 0 then we need as a default to use the safe point
> 		 //for the bound zone
> 		 if (in_pp->bind_x ==0 && in_pp->bind_y ==0 && in_pp->bind_z ==0){
> 			char *query2 = 0;
> 			MYSQL_RES *result2;
> 			MYSQL_ROW row2;
> 			if (RunQuery(query2, MakeAnyLenString(&query2, "SELECT safe_x,safe_y,safe_z FROM zone WHERE zoneidnumber=%i",in_pp->bind_zone_id), errbuf, &result2)) {
> 				if (mysql_num_rows(result2) != 0) {
> 					row2 = mysql_fetch_row(result2); 
> 					in_pp->bind_x = atof(row[0]);
> 					in_pp->bind_y = atof(row[1]);
> 					in_pp->bind_z = atof(row[2]);
> 				}
> 				mysql_free_result(result2);
> 			} else {
> 				safe_delete_array(query2);
> 				LogFile->write(EQEMuLog::Error, "Database: could not find a zone entry in database for the starting bound zone.");	
> 			}
> 
> 		 }
6569c6602,6603
< 			LogFile->write(EQEMuLog::Error, "Database: could not find start_zones entry in database. Using Defaults..");
---
> 		  LogFile->write(EQEMuLog::Error, "Database: could not find a start_zones entry in database for this choice,class,race,diety. Using Defaults..");
> 		  
6574c6608,6609
< 		LogFile->write(EQEMuLog::Error, "Database: could not find start_zones table in database. Using Defaults..");
---
> 		LogFile->write(EQEMuLog::Error, errbuf);
> 		LogFile->write(EQEMuLog::Error, "Database: SQL Error. Using Defaults..");
eq_packet_structs.h Diff
Code:
Index: eq_packet_structs.h
===================================================================
RCS file: /cvsroot/eqemu/eqemu/eqemu/Source/common/eq_packet_structs.h,v
retrieving revision 1.1.1.10
diff -r1.1.1.10 eq_packet_structs.h
151c151,156
< /*1600*/	int8	unknown1600[60];	// ***Placeholder
---
> /*1600*/	int8	haircolor[10];	
> /*1610*/	int8    beardcolor[10];
> /*1620*/	int8	eyecolor2[10];	
> /*1630*/	int8    eyecolor1[10];
> /*1640*/	int8	hair[10];	
> /*1650*/	int8    beard[10];
604,606c609,611
< 	/*0068*/	int32	haircolor; //guess
< 	/*0072*/	int32	eyecolor1; //guess
< 	/*0076*/	int32	eyecolor2; //guess
---
> 	/*0068*/	int32	haircolor;
> 	/*0072*/	int32	beard;
> 	/*0076*/	int32	beardcolor;
638,640c643,645
< /*0128*/	int32	beard;//guess
< /*0132*/	int32	beardcolor;//guess
< /*0136*/	int32	face;
---
> /*0128*/	int32   face;
> /*0132*/	int32	eyecolor1;//its possiable we could have these switched
> /*0136*/	int32	eyecolor2;//since setting one sets the other we really can't check
and finally the client_process.cpp diff
Code:
Index: client_process.cpp
===================================================================
RCS file: /cvsroot/eqemu/eqemu/eqemu/Source/zone/client_process.cpp,v
retrieving revision 1.1.1.12
diff -r1.1.1.12 client_process.cpp
98,99c98
< 	#endif
< 	
---
> 	#endif	
1098c1097
< 				case OP_Death: {
---
> 				case OP_Death: {					
1100,1101c1099
< 						break;
< 					
---
> 						break;					
1585c1583
< 				case OP_ZoneChange: {
---
> 				case OP_ZoneChange: {					
1606a1605,1606
> 					
> #ifdef GUILDWARS
1609,1618c1609,1619
< #ifdef GUILDWARS
< 					if(animation > 65 && admin<80 && CheckCheat()){
< 						if(cheater || cheatcount>0){
< 							Message(15,"Cheater log updated...yup your busted,its not nice to cheat.");
< 							char descript[50]={0};
< 							sprintf(descript,"%s: %i","Death zone cheat");
< 							database.logevents(this->AccountName(),this->AccountID(),admin,this->GetName(),"none","Death zone cheat",descript,15);
< 							if(cheater==false){
< 								worldserver.SendEmoteMessage(0,0,0,13,"<Cheater Locator> We have found a cheater.  %s (Acct: %s) was just caught hacking, please show them what we think of hackers...",this->GetName(),this->AccountName());
< 								cheater=true;
---
> 						if(animation > 65 && admin<80 && CheckCheat()){
> 							if(cheater || cheatcount>0){
> 								Message(15,"Cheater log updated...yup your busted,its not nice to cheat.");
> 								char descript[50]={0};
> 								sprintf(descript,"%s: %i","Death zone cheat");
> 								database.logevents(this->AccountName(),this->AccountID(),admin,this->GetName(),"none","Death zone cheat",descript,15);
> 								if(cheater==false){
> 									worldserver.SendEmoteMessage(0,0,0,13,"<Cheater Locator> We have found a cheater.  %s (Acct: %s) was just caught hacking, please show them what we think of hackers...",this->GetName(),this->AccountName());
> 									cheater=true;
> 								}
> 								cheatcount=0;
1620c1621,1622
< 							cheatcount=0;
---
> 							else
> 								cheatcount++;
1622,1623d1623
< 						else
< 							cheatcount++;
1625,1626d1624
< #else
< 					break;
1628c1626
< 					}
---
> 
1652,1655c1650,1651
< 		
< 					tarx=zonesummon_x;
< 					tary=zonesummon_y;
< 					tarz=zonesummon_z;
---
> 					//zone debugging
> 					ZonePoint* zp = zone_point;										
1669,1673c1665,1673
< 					else if (zonesummon_x == -3 && zonesummon_y == -3 && (zonesummon_z == -3 || zonesummon_z == -30) && database.GetZoneName(m_pp.bind_zone_id)) {
< 						strcpy(target_zone, database.GetZoneName(m_pp.bind_zone_id));
< 						tarx = m_pp.bind_x;
< 						tary = m_pp.bind_y;
< 						tarz = m_pp.bind_z;
---
> 					else if (zonesummon_x == -3 && zonesummon_y == -3 && (zonesummon_z == -3 || zonesummon_z == -30)) {						
> 						if (database.GetZoneName(m_pp.bind_zone_id)){
> 							//zoneing to bind point
> 							strcpy(target_zone, database.GetZoneName(m_pp.bind_zone_id));
> 							tarx = m_pp.bind_x;
> 							tary = m_pp.bind_y;
> 							tarz = m_pp.bind_z;
> 							
> 						} //else bind point isn't set and we will zone to the zone safe point
1693c1693
< 						tarheading = zone_point->target_heading;
---
> 						tarheading = zone_point->target_heading;						
1696a1697
> 						
1699a1701
> 						
1704c1706
< 					else {
---
> 					else {						
1707,1709c1709,1711
< 						tarx=-1;
< 						tary=-1;
< 						tarz=-1;
---
> 						//tarx=-1;
> 						//tary=-1;
> 						//tarz=-1;
1719c1721
< 					if (target_zone[0] != 0 && admin >= minstatus && GetLevel() >= minlevel) {
---
> 					if (target_zone[0] != 0 && admin >= minstatus && GetLevel() >= minlevel) {						
1737c1739
< 						if (m_pp.zone_id == zone->GetZoneID()) {
---
> 						if (m_pp.zone_id == zone->GetZoneID()) {							
1749a1752,1753
> 							//zoneing to another zone so we need to the let the world server
> 							//handle things with the client for a while
1763,1764c1767,1768
< 					else {
< 						LogFile->write(EQEMuLog::Error, "Zone %i is not available", zc->zoneID);
---
> 					else {						
> 						LogFile->write(EQEMuLog::Error, "Zone %i is not available because target wasn't found or character insufficent level", zc->zoneID);
Feel free to critique...

Ves
Reply With Quote
 


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 11:22 PM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3