More work on scripts.

This commit is contained in:
hondacrx
2023-10-13 20:25:10 -04:00
parent b2ac8035f2
commit 50cda96b45
16 changed files with 1073 additions and 732 deletions
+21
View File
@@ -167,10 +167,16 @@ namespace Game
string username;
if (!GetName(accountId, out username))
{
Global.ScriptMgr.OnFailedPasswordChange(accountId);
return AccountOpResult.NameNotExist; // account doesn't exist
}
if (newPassword.Length > MaxAccountLength)
{
Global.ScriptMgr.OnFailedPasswordChange(accountId);
return AccountOpResult.PassTooLong;
}
(byte[] salt, byte[] verifier) = SRP6.MakeRegistrationData(username, newPassword);
@@ -180,38 +186,53 @@ namespace Game
stmt.AddValue(2, accountId);
DB.Login.Execute(stmt);
Global.ScriptMgr.OnPasswordChange(accountId);
return AccountOpResult.Ok;
}
public AccountOpResult ChangeEmail(uint accountId, string newEmail)
{
if (!GetName(accountId, out _))
{
Global.ScriptMgr.OnFailedEmailChange(accountId);
return AccountOpResult.NameNotExist; // account doesn't exist
}
if (newEmail.Length > MaxEmailLength)
{
Global.ScriptMgr.OnFailedEmailChange(accountId);
return AccountOpResult.EmailTooLong;
}
PreparedStatement stmt = LoginDatabase.GetPreparedStatement(LoginStatements.UPD_EMAIL);
stmt.AddValue(0, newEmail);
stmt.AddValue(1, accountId);
DB.Login.Execute(stmt);
Global.ScriptMgr.OnEmailChange(accountId);
return AccountOpResult.Ok;
}
public AccountOpResult ChangeRegEmail(uint accountId, string newEmail)
{
if (!GetName(accountId, out _))
{
Global.ScriptMgr.OnFailedEmailChange(accountId);
return AccountOpResult.NameNotExist; // account doesn't exist
}
if (newEmail.Length > MaxEmailLength)
{
Global.ScriptMgr.OnFailedEmailChange(accountId);
return AccountOpResult.EmailTooLong;
}
PreparedStatement stmt = LoginDatabase.GetPreparedStatement(LoginStatements.UPD_REG_EMAIL);
stmt.AddValue(0, newEmail);
stmt.AddValue(1, accountId);
DB.Login.Execute(stmt);
Global.ScriptMgr.OnEmailChange(accountId);
return AccountOpResult.Ok;
}
+13 -4
View File
@@ -197,7 +197,7 @@ namespace Game.Chat
}
[Command("create", CypherStrings.CommandAccCreateHelp, RBACPermissions.CommandAccountCreate, true)]
static bool HandleAccountCreateCommand(CommandHandler handler, string accountName, string password, [OptionalArg]string email)
static bool HandleAccountCreateCommand(CommandHandler handler, string accountName, string password, [OptionalArg] string email)
{
if (accountName.Contains("@"))
{
@@ -277,6 +277,7 @@ namespace Game.Chat
if (!Global.AccountMgr.CheckEmail(handler.GetSession().GetAccountId(), oldEmail))
{
handler.SendSysMessage(CypherStrings.CommandWrongemail);
Global.ScriptMgr.OnFailedEmailChange(handler.GetSession().GetAccountId());
Log.outInfo(LogFilter.Player, "Account: {0} (IP: {1}) Character:[{2}] (GUID: {3}) Tried to change email, but the provided email [{4}] is not equal to registration email [{5}].",
handler.GetSession().GetAccountId(), handler.GetSession().GetRemoteAddress(),
handler.GetSession().GetPlayer().GetName(), handler.GetSession().GetPlayer().GetGUID().ToString(),
@@ -287,6 +288,7 @@ namespace Game.Chat
if (!Global.AccountMgr.CheckPassword(handler.GetSession().GetAccountId(), password))
{
handler.SendSysMessage(CypherStrings.CommandWrongoldpassword);
Global.ScriptMgr.OnFailedEmailChange(handler.GetSession().GetAccountId());
Log.outInfo(LogFilter.Player, "Account: {0} (IP: {1}) Character:[{2}] (GUID: {3}) Tried to change email, but the provided password is wrong.",
handler.GetSession().GetAccountId(), handler.GetSession().GetRemoteAddress(),
handler.GetSession().GetPlayer().GetName(), handler.GetSession().GetPlayer().GetGUID().ToString());
@@ -296,12 +298,14 @@ namespace Game.Chat
if (email == oldEmail)
{
handler.SendSysMessage(CypherStrings.OldEmailIsNewEmail);
Global.ScriptMgr.OnFailedEmailChange(handler.GetSession().GetAccountId());
return false;
}
if (email != emailConfirm)
{
handler.SendSysMessage(CypherStrings.NewEmailsNotMatch);
Global.ScriptMgr.OnFailedEmailChange(handler.GetSession().GetAccountId());
Log.outInfo(LogFilter.Player, "Account: {0} (IP: {1}) Character:[{2}] (GUID: {3}) Tried to change email, but the provided password is wrong.",
handler.GetSession().GetAccountId(), handler.GetSession().GetRemoteAddress(),
handler.GetSession().GetPlayer().GetName(), handler.GetSession().GetPlayer().GetGUID().ToString());
@@ -314,6 +318,7 @@ namespace Game.Chat
{
case AccountOpResult.Ok:
handler.SendSysMessage(CypherStrings.CommandEmail);
Global.ScriptMgr.OnEmailChange(handler.GetSession().GetAccountId());
Log.outInfo(LogFilter.Player, "Account: {0} (IP: {1}) Character:[{2}] (GUID: {3}) Changed Email from [{4}] to [{5}].",
handler.GetSession().GetAccountId(), handler.GetSession().GetRemoteAddress(),
handler.GetSession().GetPlayer().GetName(), handler.GetSession().GetPlayer().GetGUID().ToString(),
@@ -321,6 +326,7 @@ namespace Game.Chat
break;
case AccountOpResult.EmailTooLong:
handler.SendSysMessage(CypherStrings.EmailTooLong);
Global.ScriptMgr.OnFailedEmailChange(handler.GetSession().GetAccountId());
return false;
default:
handler.SendSysMessage(CypherStrings.CommandNotchangeemail);
@@ -340,7 +346,7 @@ namespace Game.Chat
if (!Global.AccountMgr.CheckPassword(handler.GetSession().GetAccountId(), oldPassword))
{
handler.SendSysMessage(CypherStrings.CommandWrongoldpassword);
Global.ScriptMgr.OnFailedPasswordChange(handler.GetSession().GetAccountId());
Log.outInfo(LogFilter.Player, "Account: {0} (IP: {1}) Character:[{2}] (GUID: {3}) Tried to change password, but the provided old password is wrong.",
handler.GetSession().GetAccountId(), handler.GetSession().GetRemoteAddress(),
handler.GetSession().GetPlayer().GetName(), handler.GetSession().GetPlayer().GetGUID().ToString());
@@ -351,7 +357,7 @@ namespace Game.Chat
&& !Global.AccountMgr.CheckEmail(handler.GetSession().GetAccountId(), confirmEmail)) // ... and returns false if the comparison fails.
{
handler.SendSysMessage(CypherStrings.CommandWrongemail);
Global.ScriptMgr.OnFailedPasswordChange(handler.GetSession().GetAccountId());
Log.outInfo(LogFilter.Player, "Account: {0} (IP: {1}) Character:[{2}] (GUID: {3}) Tried to change password, but the entered email [{4}] is wrong.",
handler.GetSession().GetAccountId(), handler.GetSession().GetRemoteAddress(),
handler.GetSession().GetPlayer().GetName(), handler.GetSession().GetPlayer().GetGUID().ToString(),
@@ -363,6 +369,7 @@ namespace Game.Chat
if (newPassword != confirmPassword)
{
handler.SendSysMessage(CypherStrings.NewPasswordsNotMatch);
Global.ScriptMgr.OnFailedPasswordChange(handler.GetSession().GetAccountId());
return false;
}
@@ -372,12 +379,14 @@ namespace Game.Chat
{
case AccountOpResult.Ok:
handler.SendSysMessage(CypherStrings.CommandPassword);
Global.ScriptMgr.OnPasswordChange(handler.GetSession().GetAccountId());
Log.outInfo(LogFilter.Player, "Account: {0} (IP: {1}) Character:[{2}] (GUID: {3}) Changed Password.",
handler.GetSession().GetAccountId(), handler.GetSession().GetRemoteAddress(),
handler.GetSession().GetPlayer().GetName(), handler.GetSession().GetPlayer().GetGUID().ToString());
break;
case AccountOpResult.PassTooLong:
handler.SendSysMessage(CypherStrings.PasswordTooLong);
Global.ScriptMgr.OnFailedPasswordChange(handler.GetSession().GetAccountId());
return false;
default:
handler.SendSysMessage(CypherStrings.CommandNotchangepassword);
@@ -552,7 +561,7 @@ namespace Game.Chat
{
[Command("2fa", CypherStrings.CommandAccSet2faHelp, RBACPermissions.CommandAccountSet2Fa, true)]
static bool HandleAccountSet2FACommand(CommandHandler handler, string accountName, string secret)
{
{
/*uint targetAccountId = Global.AccountMgr.GetId(accountName);
if (targetAccountId == 0)
{
+1 -1
View File
@@ -26,7 +26,7 @@ namespace Game.DungeonFinding
Global.LFGMgr.LeaveLfg(player.GetGUID(), true);
}
public override void OnLogin(Player player)
public override void OnLogin(Player player, bool firstLogin)
{
if (!Global.LFGMgr.IsOptionEnabled(LfgOptions.EnableDungeonFinder | LfgOptions.EnableRaidBrowser))
return;
+14 -13
View File
@@ -984,7 +984,8 @@ namespace Game
SendNotification(CypherStrings.ResetTalents);
}
if (pCurrChar.HasAtLoginFlag(AtLoginFlags.FirstLogin))
bool firstLogin = pCurrChar.HasAtLoginFlag(AtLoginFlags.FirstLogin);
if (firstLogin)
{
pCurrChar.RemoveAtLoginFlag(AtLoginFlags.FirstLogin);
@@ -1075,7 +1076,7 @@ namespace Game
SendNotification(CypherStrings.GmOn);
string IP_str = GetRemoteAddress();
Log.outDebug(LogFilter.Network, $"Account: {GetAccountId()} (IP: {GetRemoteAddress()}) Login Character: [{pCurrChar.GetName()}] ({pCurrChar.GetGUID()}) Level: {pCurrChar.GetLevel()}, XP: { _player.GetXP()}/{_player.GetXPForNextLevel()} ({_player.GetXPForNextLevel() - _player.GetXP()} left)");
Log.outDebug(LogFilter.Network, $"Account: {GetAccountId()} (IP: {GetRemoteAddress()}) Login Character: [{pCurrChar.GetName()}] ({pCurrChar.GetGUID()}) Level: {pCurrChar.GetLevel()}, XP: {_player.GetXP()}/{_player.GetXPForNextLevel()} ({_player.GetXPForNextLevel() - _player.GetXP()} left)");
if (!pCurrChar.IsStandState() && !pCurrChar.HasUnitState(UnitState.Stunned))
pCurrChar.SetStandState(UnitStandStateType.Stand);
@@ -1088,7 +1089,7 @@ namespace Game
// Handle Login-Achievements (should be handled after loading)
_player.UpdateCriteria(CriteriaType.Login, 1);
Global.ScriptMgr.OnPlayerLogin(pCurrChar);
Global.ScriptMgr.OnPlayerLogin(pCurrChar, firstLogin);
}
public void AbortLogin(LoginFailureReason reason)
@@ -1166,18 +1167,18 @@ namespace Game
switch (packet.Action)
{
case TutorialAction.Update:
{
byte index = (byte)(packet.TutorialBit >> 5);
if (index >= SharedConst.MaxAccountTutorialValues)
{
byte index = (byte)(packet.TutorialBit >> 5);
if (index >= SharedConst.MaxAccountTutorialValues)
{
Log.outError(LogFilter.Network, "CMSG_TUTORIAL_FLAG received bad TutorialBit {0}.", packet.TutorialBit);
return;
}
uint flag = GetTutorialInt(index);
flag |= (uint)(1 << (int)(packet.TutorialBit & 0x1F));
SetTutorialInt(index, flag);
break;
Log.outError(LogFilter.Network, "CMSG_TUTORIAL_FLAG received bad TutorialBit {0}.", packet.TutorialBit);
return;
}
uint flag = GetTutorialInt(index);
flag |= (uint)(1 << (int)(packet.TutorialBit & 0x1F));
SetTutorialInt(index, flag);
break;
}
case TutorialAction.Clear:
for (byte i = 0; i < SharedConst.MaxAccountTutorialValues; ++i)
SetTutorialInt(i, 0xFFFFFFFF);
+9
View File
@@ -586,6 +586,8 @@ namespace Game.Networking
{
SendAuthResponseError(BattlenetRpcErrorCode.RiskAccountLocked);
Log.outDebug(LogFilter.Network, "HandleAuthSession: Sent Auth Response (Account IP differs).");
// We could log on hook only instead of an additional db log, however action logger is config based. Better keep DB logging as well
Global.ScriptMgr.OnFailedAccountLogin(account.game.Id);
CloseSocket();
return;
}
@@ -596,6 +598,8 @@ namespace Game.Networking
{
SendAuthResponseError(BattlenetRpcErrorCode.RiskAccountLocked);
Log.outDebug(LogFilter.Network, "WorldSocket.HandleAuthSession: Sent Auth Response (Account country differs. Original country: {0}, new country: {1}).", account.battleNet.LockCountry, _ipCountry);
// We could log on hook only instead of an additional db log, however action logger is config based. Better keep DB logging as well
Global.ScriptMgr.OnFailedAccountLogin(account.game.Id);
CloseSocket();
return;
}
@@ -617,6 +621,7 @@ namespace Game.Networking
{
SendAuthResponseError(BattlenetRpcErrorCode.GameAccountBanned);
Log.outError(LogFilter.Network, "WorldSocket:HandleAuthSession: Sent Auth Response (Account banned).");
Global.ScriptMgr.OnFailedAccountLogin(account.game.Id);
CloseSocket();
return;
}
@@ -627,6 +632,7 @@ namespace Game.Networking
{
SendAuthResponseError(BattlenetRpcErrorCode.ServerIsPrivate);
Log.outInfo(LogFilter.Network, "WorldSocket:HandleAuthSession: User tries to login but his security level is not enough");
Global.ScriptMgr.OnFailedAccountLogin(account.game.Id);
CloseSocket();
return;
}
@@ -642,6 +648,9 @@ namespace Game.Networking
DB.Login.Execute(stmt);
}
// At this point, we can safely hook a successful login
Global.ScriptMgr.OnAccountLogin(account.game.Id);
_worldSession = new WorldSession(account.game.Id, authSession.RealmJoinTicket, account.battleNet.Id, this, account.game.Security, (Expansion)account.game.Expansion,
mutetime, account.game.OS, account.battleNet.Locale, account.game.Recruiter, account.game.IsRectuiter);
+27 -1
View File
@@ -653,7 +653,7 @@ namespace Game.Scripting
public virtual void OnSpellCast(Player player, Spell spell, bool skipCheck) { }
// Called when a player logs in.
public virtual void OnLogin(Player player) { }
public virtual void OnLogin(Player player, bool firstLogin) { }
// Called when a player logs out.
public virtual void OnLogout(Player player) { }
@@ -692,6 +692,32 @@ namespace Game.Scripting
public virtual void OnPlayerChoiceResponse(Player player, uint choiceId, uint responseId) { }
}
public class AccountScript : ScriptObject
{
public AccountScript(string name) : base(name)
{
Global.ScriptMgr.AddScript(this);
}
// Called when an account logged in succesfully
public virtual void OnAccountLogin(uint accountId) { }
// Called when an account login failed
public virtual void OnFailedAccountLogin(uint accountId) { }
// Called when Email is successfully changed for Account
public virtual void OnEmailChange(uint accountId) { }
// Called when Email failed to change for Account
public virtual void OnFailedEmailChange(uint accountId) { }
// Called when Password is successfully changed for Account
public virtual void OnPasswordChange(uint accountId) { }
// Called when Password failed to change for Account
public virtual void OnFailedPasswordChange(uint accountId) { }
}
public class GuildScript : ScriptObject
{
public GuildScript(string name) : base(name)
+32 -5
View File
@@ -147,6 +147,7 @@ namespace Game.Scripting
case "TransportScript":
case "AchievementCriteriaScript":
case "PlayerScript":
case "AccountScript":
case "GuildScript":
case "GroupScript":
case "AreaTriggerEntityScript":
@@ -267,7 +268,7 @@ namespace Game.Scripting
{
UnitAI.FillAISpellInfo();
}
public List<SplineChainLink> GetSplineChain(Creature who, ushort chainId)
{
return GetSplineChain(who.GetEntry(), chainId);
@@ -762,7 +763,7 @@ namespace Game.Scripting
RunScript<AchievementScript>(p => p.OnCompleted(player, achievement), Global.AchievementMgr.GetAchievementScriptId(achievement.Id));
}
// AchievementCriteriaScript
public bool OnCriteriaCheck(uint ScriptId, Player source, Unit target)
{
@@ -855,9 +856,9 @@ namespace Game.Scripting
{
ForEach<PlayerScript>(p => p.OnSpellCast(player, spell, skipCheck));
}
public void OnPlayerLogin(Player player)
public void OnPlayerLogin(Player player, bool firstLogin)
{
ForEach<PlayerScript>(p => p.OnLogin(player));
ForEach<PlayerScript>(p => p.OnLogin(player, firstLogin));
}
public void OnPlayerLogout(Player player)
{
@@ -904,6 +905,32 @@ namespace Game.Scripting
ForEach<PlayerScript>(p => p.OnPlayerChoiceResponse(player, choiceId, responseId));
}
// Account
public void OnAccountLogin(uint accountId)
{
ForEach<AccountScript>(script => script.OnAccountLogin(accountId));
}
public void OnFailedAccountLogin(uint accountId)
{
ForEach<AccountScript>(script => script.OnFailedAccountLogin(accountId));
}
public void OnEmailChange(uint accountId)
{
ForEach<AccountScript>(script => script.OnEmailChange(accountId));
}
public void OnFailedEmailChange(uint accountId)
{
ForEach<AccountScript>(script => script.OnFailedEmailChange(accountId));
}
public void OnPasswordChange(uint accountId)
{
ForEach<AccountScript>(script => script.OnPasswordChange(accountId));
}
public void OnFailedPasswordChange(uint accountId)
{
ForEach<AccountScript>(script => script.OnFailedPasswordChange(accountId));
}
// GuildScript
public void OnGuildAddMember(Guild guild, Player player, byte plRank)
{
@@ -1172,7 +1199,7 @@ namespace Game.Scripting
uint _ScriptCount;
public Dictionary<uint, SpellSummary> spellSummaryStorage = new();
Hashtable ScriptStorage = new();
// creature entry + chain ID
MultiMap<Tuple<uint, ushort>, SplineChainLink> m_mSplineChainsMap = new(); // spline chains
}