caller2<bool, const char*, size_t> rememberer;
bool forcequit;
const unsigned char * lowermap_rememberer;
+ unsigned char prev_map[256];
+
+ void CheckRehash()
+ {
+ // See if anything changed
+ if (!memcmp(prev_map, national_case_insensitive_map, sizeof(prev_map)))
+ return;
+
+ memcpy(prev_map, national_case_insensitive_map, sizeof(prev_map));
+
+ ServerInstance->RehashUsersAndChans();
+
+ // The OnGarbageCollect() method in m_watch rebuilds the hashmap used by it
+ Module* mod = ServerInstance->Modules->Find("m_watch.so");
+ if (mod)
+ mod->OnGarbageCollect();
+
+ // Send a Request to m_spanningtree asking it to rebuild its hashmaps
+ mod = ServerInstance->Modules->Find("m_spanningtree.so");
+ if (mod)
+ {
+ Request req(this, mod, "rehash");
+ req.Send();
+ }
+ }
public:
- ModuleNationalChars() : rememberer(ServerInstance->IsNick)
+ ModuleNationalChars()
+ : rememberer(ServerInstance->IsNick), lowermap_rememberer(national_case_insensitive_map)
+ {
+ memcpy(prev_map, national_case_insensitive_map, sizeof(prev_map));
+ }
+
+ void init()
{
- lowermap_rememberer = national_case_insensitive_map;
memcpy(m_lower, rfc_case_insensitive_map, 256);
national_case_insensitive_map = m_lower;
ServerInstance->IsNick = &myhandler;
Implementation eventlist[] = { I_OnRehash, I_On005Numeric };
- ServerInstance->Modules->Attach(eventlist, this, 2);
+ ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
OnRehash(NULL);
}
virtual void OnRehash(User* user)
{
- ConfigReader conf;
- charset = conf.ReadValue("nationalchars", "file", 0);
- casemapping = conf.ReadValue("nationalchars", "casemapping", charset, 0, false);
+ ConfigTag* tag = ServerInstance->Config->ConfValue("nationalchars");
+ charset = tag->getString("file");
+ casemapping = tag->getString("casemapping", ServerConfig::CleanFilename(charset.c_str()));
+ if (casemapping.find(' ') != std::string::npos)
+ throw ModuleException("<nationalchars:casemapping> must not contain any spaces!");
+#if defined _WIN32
+ if (!ServerInstance->Config->StartsWithWindowsDriveLetter(charset))
+ charset.insert(0, "./locales/");
+#else
if(charset[0] != '/')
charset.insert(0, "../locales/");
+#endif
unsigned char * tables[8] = { m_additional, m_additionalMB, m_additionalUp, m_lower, m_upper, m_additionalUtf8, m_additionalUtf8range, m_additionalUtf8interval };
- loadtables(charset, tables, 8, 5);
- forcequit = conf.ReadFlag("nationalchars", "forcequit", 0);
+ if (!loadtables(charset, tables, 8, 5))
+ throw ModuleException("The locale file failed to load. Check your log file for more information.");
+ forcequit = tag->getBool("forcequit");
CheckForceQuit("National character set changed");
+ CheckRehash();
}
void CheckForceQuit(const char * message)
if (!forcequit)
return;
- for (std::vector<LocalUser*>::iterator iter = ServerInstance->Users->local_users.begin(); iter != ServerInstance->Users->local_users.end(); ++iter)
+ for (LocalUserList::const_iterator iter = ServerInstance->Users->local_users.begin(); iter != ServerInstance->Users->local_users.end(); ++iter)
{
/* Fix by Brain: Dont quit UID users */
User* n = *iter;
ServerInstance->IsNick = rememberer;
national_case_insensitive_map = lowermap_rememberer;
CheckForceQuit("National characters module unloaded");
+ CheckRehash();
}
virtual Version GetVersion()
}
/*so Bynets Unreal distribution stuff*/
- void loadtables(std::string filename, unsigned char ** tables, unsigned char cnt, char faillimit)
+ bool loadtables(std::string filename, unsigned char ** tables, unsigned char cnt, char faillimit)
{
std::ifstream ifs(filename.c_str());
if (ifs.fail())
{
ServerInstance->Logs->Log("m_nationalchars",DEFAULT,"loadtables() called for missing file: %s", filename.c_str());
- return;
+ return false;
}
for (unsigned char n=0; n< cnt; n++)
if (loadtable(ifs, tables[n], 255) && (n < faillimit))
{
ServerInstance->Logs->Log("m_nationalchars",DEFAULT,"loadtables() called for illegal file: %s (line %d)", filename.c_str(), n+1);
- return;
+ return false;
}
}
makereverse(m_additional, m_reverse_additional, sizeof(m_additional));
+ return true;
}
unsigned char symtoi(const char *t,unsigned char base)