mirror of
https://github.com/mm201/pkmn-classic-framework.git
synced 2026-09-08 02:05:13 -05:00
Lock a GTS offer when initiating a trade.
This commit is contained in:
@@ -443,6 +443,14 @@ namespace PkmnFoundations.GTS
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Database.Instance.GtsLockPokemon4(targetPid, pid))
|
||||
{
|
||||
// failed to acquire lock, implying someone else beat us here. Say already traded.
|
||||
SessionManager.Remove(session);
|
||||
response.Write(new byte[] { 0x02, 0x00 }, 0, 2);
|
||||
break;
|
||||
}
|
||||
|
||||
// uncomment these two lines if you're replaying gamestats requests and need to skip the random token
|
||||
//session = new GamestatsSession(this.GameId, this.Salt, pid, "/pokemondpds/worldexchange/exchange.asp");
|
||||
//SessionManager.Add(session);
|
||||
|
||||
@@ -406,6 +406,14 @@ namespace PkmnFoundations.GTS
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Database.Instance.GtsLockPokemon5(targetPid, pid))
|
||||
{
|
||||
// failed to acquire lock, implying someone else beat us here. Say already traded.
|
||||
SessionManager.Remove(session);
|
||||
response.Write(new byte[] { 0x02, 0x00 }, 0, 2);
|
||||
break;
|
||||
}
|
||||
|
||||
object[] tag = new GtsRecord5[2];
|
||||
tag[0] = upload;
|
||||
tag[1] = result;
|
||||
|
||||
@@ -349,6 +349,23 @@ namespace PkmnFoundations.Data
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool GtsLockPokemon4(int offer_pid, int partner_pid)
|
||||
{
|
||||
return WithTransaction(tran => GtsLockPokemon4(offer_pid, partner_pid));
|
||||
}
|
||||
|
||||
public bool GtsLockPokemon4(MySqlTransaction tran, int offer_pid, int partner_pid)
|
||||
{
|
||||
DateTime now = DateTime.UtcNow;
|
||||
int rows = tran.ExecuteNonQuery("UPDATE GtsPokemon4 SET LockedUntil = @locked_until, LockedBy = @locked_by " +
|
||||
"WHERE LockedUntil < @now OR LockedUntil IS NULL",
|
||||
new MySqlParameter("@locked_until", now.AddSeconds(GTS_LOCK_DURATION)),
|
||||
new MySqlParameter("@locked_by", partner_pid),
|
||||
new MySqlParameter("@now", now));
|
||||
|
||||
return rows > 0;
|
||||
}
|
||||
|
||||
public override bool GtsTradePokemon4(GtsRecord4 upload, GtsRecord4 result, int partner_pid)
|
||||
{
|
||||
return WithTransactionSuccessful(tran => GtsTradePokemon4(tran, upload, result, partner_pid));
|
||||
@@ -1520,6 +1537,23 @@ namespace PkmnFoundations.Data
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool GtsLockPokemon5(int offer_pid, int partner_pid)
|
||||
{
|
||||
return WithTransaction(tran => GtsLockPokemon5(offer_pid, partner_pid));
|
||||
}
|
||||
|
||||
public bool GtsLockPokemon5(MySqlTransaction tran, int offer_pid, int partner_pid)
|
||||
{
|
||||
DateTime now = DateTime.UtcNow;
|
||||
int rows = tran.ExecuteNonQuery("UPDATE GtsPokemon5 SET LockedUntil = @locked_until, LockedBy = @locked_by " +
|
||||
"WHERE LockedUntil < @now OR LockedUntil IS NULL",
|
||||
new MySqlParameter("@locked_until", now.AddSeconds(GTS_LOCK_DURATION)),
|
||||
new MySqlParameter("@locked_by", partner_pid),
|
||||
new MySqlParameter("@now", now));
|
||||
|
||||
return rows > 0;
|
||||
}
|
||||
|
||||
public override bool GtsTradePokemon5(GtsRecord5 upload, GtsRecord5 result, int partner_pid)
|
||||
{
|
||||
return WithTransactionSuccessful(tran => GtsTradePokemon5(tran, upload, result, partner_pid));
|
||||
@@ -2491,6 +2525,10 @@ namespace PkmnFoundations.Data
|
||||
|
||||
private void BattleVideoUpdateHypeTimes(MySqlTransaction tran, string tableName, DateTime hypeTime)
|
||||
{
|
||||
// todo: run this less often by caching the HypeTimestamp somewhere
|
||||
// run it only once a week
|
||||
// use cached timestamp for insertions/updates too
|
||||
|
||||
// common case: HypeTimestamp is in the past and needs to be updated and decay applied.
|
||||
tran.ExecuteNonQuery("UPDATE " + tableName + " " +
|
||||
"SET Hype = Hype / (1 << FLOOR(DATEDIFF(@hypetime, HypeTimestamp) / @decay)), HypeTimestamp = @hypetime " +
|
||||
|
||||
@@ -96,6 +96,8 @@ namespace PkmnFoundations.Data
|
||||
return dateNow.AddDays(-(int)dateNow.DayOfWeek);
|
||||
}
|
||||
|
||||
internal const double GTS_LOCK_DURATION = 60.0d;
|
||||
|
||||
#endregion
|
||||
|
||||
#region GTS 4
|
||||
@@ -108,6 +110,8 @@ namespace PkmnFoundations.Data
|
||||
|
||||
public abstract bool GtsDeletePokemon4(int pid);
|
||||
|
||||
public abstract bool GtsLockPokemon4(int offer_pid, int partner_pid);
|
||||
|
||||
public abstract bool GtsTradePokemon4(int pidSrc, int pidDest);
|
||||
public abstract bool GtsTradePokemon4(GtsRecord4 upload, GtsRecord4 result, int partner_pid);
|
||||
|
||||
@@ -158,6 +162,8 @@ namespace PkmnFoundations.Data
|
||||
|
||||
public abstract bool GtsDeletePokemon5(int pid);
|
||||
|
||||
public abstract bool GtsLockPokemon5(int offer_pid, int partner_pid);
|
||||
|
||||
public abstract bool GtsTradePokemon5(int pidSrc, int pidDest);
|
||||
public abstract bool GtsTradePokemon5(GtsRecord5 upload, GtsRecord5 result, int partner_pid);
|
||||
|
||||
|
||||
@@ -329,7 +329,9 @@ CREATE TABLE IF NOT EXISTS `GtsPokemon4` (
|
||||
`IsExchanged` tinyint(3) unsigned NOT NULL,
|
||||
`TrainerVersion` tinyint(3) unsigned NOT NULL,
|
||||
`TrainerLanguage` tinyint(3) unsigned NOT NULL,
|
||||
`ParseVersion` int(11) unsigned DEFAULT NULL,
|
||||
`ParseVersion` int(10) unsigned DEFAULT NULL,
|
||||
`LockedBy` int(11) DEFAULT NULL,
|
||||
`LockedUntil` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `pid` (`pid`),
|
||||
KEY `Species` (`Species`),
|
||||
@@ -368,6 +370,8 @@ CREATE TABLE IF NOT EXISTS `GtsPokemon5` (
|
||||
`TrainerBadges` tinyint(3) unsigned NOT NULL,
|
||||
`TrainerUnityTower` tinyint(3) unsigned NOT NULL,
|
||||
`ParseVersion` int(10) unsigned DEFAULT NULL,
|
||||
`LockedBy` int(11) DEFAULT NULL,
|
||||
`LockedUntil` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `pid` (`pid`),
|
||||
KEY `Species` (`Species`),
|
||||
|
||||
Reference in New Issue
Block a user