[Character Creation] Improved Random Name Generator (#4081)

* test against vanilla branch

* use existing methods to validate name instead of raw sql

* Revert "use existing methods to validate name instead of raw sql"

This reverts commit 43750c6f4f597864f3e433885f9e3f84144e3d65.

* ReserveName doesn't work like that. Oops. Well, check against Name Filter at least.

* That db access condition was wrong.

* that isn't how CheckNameFilter works, either.

* apply editorconfig w/ trivial change

* Actually apply editorconfig changes.
This commit is contained in:
catapultam-habeo 2024-02-26 23:15:40 -06:00 committed by GitHub
parent 2da6190950
commit 89be55254e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -599,79 +599,63 @@ bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app)
} }
bool Client::HandleGenerateRandomNamePacket(const EQApplicationPacket *app) { bool Client::HandleGenerateRandomNamePacket(const EQApplicationPacket *app) {
// creates up to a 10 char name char newName[17] = {0};
char vowels[18]="aeiouyaeiouaeioe"; bool unique = false;
char cons[48]="bcdfghjklmnpqrstvwxzybcdgklmnprstvwbcdgkpstrkd";
char rndname[17]="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; while (!unique) {
char paircons[33]="ngrkndstshthphsktrdrbrgrfrclcr"; std::string cons = "bcdfghjklmnpqrstvwxyz";
int rndnum=emu_random.Int(0, 75),n=1; std::string vows = "aeou";
bool dlc=false; std::string allVows = "aeiou";
bool vwl=false; std::vector<std::string> endPhon = {"a", "e", "i", "o", "u", "os", "as", "us", "is", "y", "an", "en", "in", "on", "un"};
bool dbl=false;
if (rndnum>63) std::random_device rd;
{ // rndnum is 0 - 75 where 64-75 is cons pair, 17-63 is cons, 0-16 is vowel std::mt19937 gen(rd());
rndnum=(rndnum-61)*2; // name can't start with "ng" "nd" or "rk"
rndname[0]=paircons[rndnum]; std::uniform_int_distribution<int> lenDist(5, 10);
rndname[1]=paircons[rndnum+1]; std::uniform_int_distribution<int> firstCharDist(0, 1);
n=2; std::uniform_int_distribution<int> consDist(0, cons.size() - 1);
} std::uniform_int_distribution<int> vowDist(0, vows.size() - 1);
else if (rndnum>16) std::uniform_int_distribution<int> allVowDist(0, allVows.size() - 1);
{ std::uniform_int_distribution<int> endPhonDist(0, endPhon.size() - 1);
rndnum-=17;
rndname[0]=cons[rndnum]; int len = 0;
} memset(newName, 0, sizeof(newName));
else
{ if (firstCharDist(gen) == 0) {
rndname[0]=vowels[rndnum]; newName[len++] = vows[vowDist(gen)];
vwl=true; newName[len++] = cons[consDist(gen)];
} } else {
int namlen=emu_random.Int(5, 10); newName[len++] = cons[consDist(gen)];
for (int i=n;i<namlen;i++) newName[len++] = allVows[allVowDist(gen)];
{ }
dlc=false;
if (vwl) //last char was a vowel newName[0] = toupper(newName[0]);
{ // so pick a cons or cons pair
rndnum=emu_random.Int(0, 62); while (len < lenDist(gen) - 1) {
if (rndnum>46) if (len % 2 == 0) {
{ // pick a cons pair newName[len++] = cons[consDist(gen)];
if (i>namlen-3) // last 2 chars in name? } else {
{ // name can only end in cons pair "rk" "st" "sh" "th" "ph" "sk" "nd" or "ng" newName[len++] = allVows[allVowDist(gen)];
rndnum=emu_random.Int(0, 7)*2;
}
else
{ // pick any from the set
rndnum=(rndnum-47)*2;
}
rndname[i]=paircons[rndnum];
rndname[i+1]=paircons[rndnum+1];
dlc=true; // flag keeps second letter from being doubled below
i+=1;
}
else
{ // select a single cons
rndname[i]=cons[rndnum];
} }
} }
else
{ // select a vowel std::string end = endPhon[endPhonDist(gen)];
rndname[i]=vowels[emu_random.Int(0, 16)]; for (char c : end) {
if (len < 10) newName[len++] = c;
} }
vwl=!vwl;
if (!dbl && !dlc) if (database.CheckNameFilter(newName)) {
{ // one chance at double letters in name std::string query = StringFormat("SELECT `name` FROM `character_data` WHERE `name` = '%s'", newName);
if (!emu_random.Int(0, i+9)) // chances decrease towards end of name auto res = database.QueryDatabase(query);
{ if (res.Success() && res.RowCount() == 0) {
rndname[i+1]=rndname[i]; unique = true;
dbl=true;
i+=1;
} }
} }
} }
rndname[0]=toupper(rndname[0]);
NameGeneration_Struct* ngs = (NameGeneration_Struct*)app->pBuffer; NameGeneration_Struct* ngs = (NameGeneration_Struct*)app->pBuffer;
memset(ngs->name,0,64); memset(ngs->name, 0, 64);
strcpy(ngs->name,rndname); strcpy(ngs->name, newName);
QueuePacket(app); QueuePacket(app);
return true; return true;