mirror of
https://github.com/mm201/pkmn-classic-framework.git
synced 2026-09-29 21:06:27 -05:00
Log user IP addresses.
This commit is contained in:
@@ -12,6 +12,10 @@
|
||||
providerName="MySql.Data.MySqlClient" />
|
||||
</connectionStrings>
|
||||
|
||||
<appSettings>
|
||||
<add key="AllowedProxies" value="::1,127.0.0.1,178.62.43.212,195.201.236.139,172.104.88.237" />
|
||||
</appSettings>
|
||||
|
||||
<system.web>
|
||||
<compilation debug="true" targetFramework="4.0" />
|
||||
<!--
|
||||
|
||||
@@ -122,6 +122,7 @@
|
||||
</Compile>
|
||||
<Compile Include="src\AppStateHelper.cs" />
|
||||
<Compile Include="src\FakeOpponentGenerator4.cs" />
|
||||
<Compile Include="src\IpAddressHelper.cs" />
|
||||
<Compile Include="syachi2ds.ashx.cs">
|
||||
<DependentUpon>syachi2ds.ashx</DependentUpon>
|
||||
</Compile>
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace PkmnFoundations.GTS
|
||||
#endif
|
||||
byte[] profileBinary = new byte[100];
|
||||
Array.Copy(data, 0, profileBinary, 0, 100);
|
||||
TrainerProfile4 profile = new TrainerProfile4(pid, profileBinary);
|
||||
TrainerProfile4 profile = new TrainerProfile4(pid, profileBinary, IpAddressHelper.GetIpAddress(context.Request));
|
||||
Database.Instance.GamestatsSetProfile4(profile);
|
||||
#if !DEBUG
|
||||
}
|
||||
@@ -124,7 +124,7 @@ namespace PkmnFoundations.GTS
|
||||
// todo: find out the meaning of this request.
|
||||
// is it simply done to check whether the GTS is online?
|
||||
|
||||
Database.Instance.GamestatsBumpProfile4(pid);
|
||||
Database.Instance.GamestatsBumpProfile4(pid, IpAddressHelper.GetIpAddress(context.Request));
|
||||
response.Write(new byte[] { 0x01, 0x00 }, 0, 2);
|
||||
break;
|
||||
|
||||
@@ -510,7 +510,7 @@ namespace PkmnFoundations.GTS
|
||||
SessionManager.Remove(session);
|
||||
|
||||
// Probably an availability/status code.
|
||||
Database.Instance.GamestatsBumpProfile4(pid);
|
||||
Database.Instance.GamestatsBumpProfile4(pid, IpAddressHelper.GetIpAddress(context.Request));
|
||||
|
||||
// Response codes:
|
||||
// 0x00: BSOD
|
||||
|
||||
36
gts/src/IpAddressHelper.cs
Normal file
36
gts/src/IpAddressHelper.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
namespace PkmnFoundations.GTS
|
||||
{
|
||||
public static class IpAddressHelper
|
||||
{
|
||||
public static string GetIpAddress(HttpRequest request)
|
||||
{
|
||||
var allowedProxies = ConfigurationManager.AppSettings["AllowedProxies"].Split(',').Select(s => s.Trim());
|
||||
string hostAddress = RemovePort(request.UserHostAddress.Trim());
|
||||
|
||||
if (!allowedProxies.Contains(hostAddress)) return hostAddress; // return real IP if not a blessed proxy
|
||||
|
||||
var xForwardedFor = request.Headers["X-Forwarded-For"].Split(',').Select(s => RemovePort(s.Trim()));
|
||||
foreach (string s in xForwardedFor.Reverse())
|
||||
{
|
||||
if (!allowedProxies.Contains(s)) return s; // return LAST IP in the proxy chain that's not trusted. (everything coming earlier could be spoofed)
|
||||
}
|
||||
|
||||
// these conditions can only happen if the real user is at a blessed proxy IP address. (probably localhost)
|
||||
return xForwardedFor.FirstOrDefault() ?? hostAddress;
|
||||
}
|
||||
|
||||
private static string RemovePort(string ip)
|
||||
{
|
||||
if (ip.Contains(':') && ip.Contains('.'))
|
||||
return ip.Substring(0, ip.IndexOf(':'));
|
||||
else
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ namespace PkmnFoundations.GTS
|
||||
// Specifically, email, notification status, and the two secrets appear to always be 0.
|
||||
byte[] profileBinary = new byte[100];
|
||||
Array.Copy(request, 0, profileBinary, 0, 100);
|
||||
TrainerProfile5 profile = new TrainerProfile5(pid, profileBinary);
|
||||
TrainerProfile5 profile = new TrainerProfile5(pid, profileBinary, IpAddressHelper.GetIpAddress(context.Request));
|
||||
Database.Instance.GamestatsSetProfile5(profile);
|
||||
#if !DEBUG
|
||||
}
|
||||
|
||||
@@ -1056,12 +1056,12 @@ namespace PkmnFoundations.Data
|
||||
#endregion
|
||||
|
||||
#region Other Gamestats 4
|
||||
public override bool GamestatsBumpProfile4(int pid)
|
||||
public override bool GamestatsBumpProfile4(int pid, string ip_address)
|
||||
{
|
||||
return WithTransaction(tran => GamestatsBumpProfile4(tran, pid));
|
||||
return WithTransaction(tran => GamestatsBumpProfile4(tran, pid, ip_address));
|
||||
}
|
||||
|
||||
public bool GamestatsBumpProfile4(MySqlTransaction tran, int pid)
|
||||
public bool GamestatsBumpProfile4(MySqlTransaction tran, int pid, string ip_address)
|
||||
{
|
||||
bool exists = Convert.ToSByte(tran.ExecuteScalar("SELECT EXISTS(SELECT * FROM GtsProfiles4 WHERE pid = @pid)",
|
||||
new MySqlParameter("@pid", pid))) != 0;
|
||||
@@ -1069,13 +1069,18 @@ namespace PkmnFoundations.Data
|
||||
if (exists)
|
||||
{
|
||||
return tran.ExecuteNonQuery("UPDATE GtsProfiles4 SET " +
|
||||
"TimeUpdated = UTC_TIMESTAMP() WHERE pid = @pid", new MySqlParameter("@pid", pid)) > 0;
|
||||
"TimeUpdated = UTC_TIMESTAMP(), IpAddress = @ip_address " +
|
||||
"WHERE pid = @pid",
|
||||
new MySqlParameter("@ip_address", ip_address),
|
||||
new MySqlParameter("@pid", pid)) > 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return tran.ExecuteNonQuery("INSERT INTO GtsProfiles4 " +
|
||||
"(pid, TimeAdded, TimeUpdated) VALUES (@pid, UTC_TIMESTAMP(), " +
|
||||
"UTC_TIMESTAMP())", new MySqlParameter("@pid", pid)) > 0;
|
||||
"(pid, TimeAdded, TimeUpdated, IpAddress) VALUES (@pid, UTC_TIMESTAMP(), " +
|
||||
"UTC_TIMESTAMP(), @ip_address)",
|
||||
new MySqlParameter("@pid", pid),
|
||||
new MySqlParameter("@ip_address", ip_address)) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1104,7 +1109,8 @@ namespace PkmnFoundations.Data
|
||||
new MySqlParameter("@email", profile.Email),
|
||||
new MySqlParameter("@has_notifications", profile.HasNotifications),
|
||||
new MySqlParameter("@client_secret", profile.ClientSecret),
|
||||
new MySqlParameter("@mail_secret", profile.MailSecret)
|
||||
new MySqlParameter("@mail_secret", profile.MailSecret),
|
||||
new MySqlParameter("@ip_address", profile.IpAddress)
|
||||
};
|
||||
|
||||
if (exists)
|
||||
@@ -1114,7 +1120,7 @@ namespace PkmnFoundations.Data
|
||||
"Region = @region, OT = @ot, Name = @name, MacAddress = @mac_address, " +
|
||||
"Email = @email, HasNotifications = @has_notifications, " +
|
||||
"ClientSecret = @client_secret, MailSecret = @mail_secret, " +
|
||||
"ParseVersion = 2, TimeUpdated = UTC_TIMESTAMP() " +
|
||||
"IpAddress = @ip_address, ParseVersion = 2, TimeUpdated = UTC_TIMESTAMP() " +
|
||||
"WHERE pid = @pid", _params) > 0;
|
||||
}
|
||||
else
|
||||
@@ -1122,10 +1128,10 @@ namespace PkmnFoundations.Data
|
||||
return tran.ExecuteNonQuery("INSERT INTO GtsProfiles4 " +
|
||||
"(pid, Data, Version, Language, Country, Region, OT, Name, " +
|
||||
"MacAddress, Email, HasNotifications, ClientSecret, MailSecret, " +
|
||||
"ParseVersion, TimeAdded, TimeUpdated) VALUES " +
|
||||
"IpAddress, ParseVersion, TimeAdded, TimeUpdated) VALUES " +
|
||||
"(@pid, @data, @version, @language, @country, @region, @ot, " +
|
||||
"@name, @mac_address, @email, @has_notifications, " +
|
||||
"@client_secret, @mail_secret, 2, UTC_TIMESTAMP(), UTC_TIMESTAMP())", _params) > 0;
|
||||
"@client_secret, @mail_secret, @ip_address, 2, UTC_TIMESTAMP(), UTC_TIMESTAMP())", _params) > 0;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
@@ -2025,7 +2031,8 @@ namespace PkmnFoundations.Data
|
||||
new MySqlParameter("@email", profile.Email),
|
||||
new MySqlParameter("@has_notifications", profile.HasNotifications),
|
||||
new MySqlParameter("@client_secret", profile.ClientSecret),
|
||||
new MySqlParameter("@mail_secret", profile.MailSecret)
|
||||
new MySqlParameter("@mail_secret", profile.MailSecret),
|
||||
new MySqlParameter("@ip_address", profile.IpAddress)
|
||||
};
|
||||
|
||||
if (exists)
|
||||
@@ -2035,7 +2042,7 @@ namespace PkmnFoundations.Data
|
||||
"Region = @region, OT = @ot, Name = @name, MacAddress = @mac_address, " +
|
||||
"Email = @email, HasNotifications = @has_notifications, " +
|
||||
"ClientSecret = @client_secret, MailSecret = @mail_secret, " +
|
||||
"ParseVersion = 2, TimeUpdated = UTC_TIMESTAMP() " +
|
||||
"IpAddress = @ip_address, ParseVersion = 2, TimeUpdated = UTC_TIMESTAMP() " +
|
||||
"WHERE pid = @pid", _params) > 0;
|
||||
}
|
||||
else
|
||||
@@ -2043,10 +2050,10 @@ namespace PkmnFoundations.Data
|
||||
return tran.ExecuteNonQuery("INSERT INTO GtsProfiles5 " +
|
||||
"(pid, Data, Version, Language, Country, Region, OT, Name, " +
|
||||
"MacAddress, Email, HasNotifications, ClientSecret, MailSecret, " +
|
||||
"ParseVersion, TimeAdded, TimeUpdated) VALUES " +
|
||||
"IpAddress, ParseVersion, TimeAdded, TimeUpdated) VALUES " +
|
||||
"(@pid, @data, @version, @language, @country, @region, @ot, " +
|
||||
"@name, @mac_address, @email, @has_notifications, " +
|
||||
"@client_secret, @mail_secret, 2, UTC_TIMESTAMP(), UTC_TIMESTAMP())", _params) > 0;
|
||||
"@client_secret, @mail_secret, @ip_address, 2, UTC_TIMESTAMP(), UTC_TIMESTAMP())", _params) > 0;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace PkmnFoundations.Data
|
||||
#endregion
|
||||
|
||||
#region Other Gamestats 4
|
||||
public abstract bool GamestatsBumpProfile4(int pid);
|
||||
public abstract bool GamestatsBumpProfile4(int pid, string ip_address);
|
||||
public abstract bool GamestatsSetProfile4(TrainerProfile4 profile);
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace PkmnFoundations.Structures
|
||||
{
|
||||
}
|
||||
|
||||
public TrainerProfile4(int pid, byte[] data) : base(pid, data)
|
||||
public TrainerProfile4(int pid, byte[] data, string ip_address) : base(pid, data, ip_address)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace PkmnFoundations.Structures
|
||||
|
||||
public TrainerProfile4 Clone()
|
||||
{
|
||||
return new TrainerProfile4(PID, Data.ToArray());
|
||||
return new TrainerProfile4(PID, Data.ToArray(), IpAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace PkmnFoundations.Structures
|
||||
{
|
||||
}
|
||||
|
||||
public TrainerProfile5(int pid, byte[] data) : base(pid, data)
|
||||
public TrainerProfile5(int pid, byte[] data, string ip_address) : base(pid, data, ip_address)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace PkmnFoundations.Structures
|
||||
|
||||
public TrainerProfile5 Clone()
|
||||
{
|
||||
return new TrainerProfile5(PID, Data.ToArray());
|
||||
return new TrainerProfile5(PID, Data.ToArray(), IpAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,17 +13,19 @@ namespace PkmnFoundations.Structures
|
||||
|
||||
}
|
||||
|
||||
protected TrainerProfileBase(int pid, byte[] data)
|
||||
protected TrainerProfileBase(int pid, byte[] data, string ip_address)
|
||||
{
|
||||
if (data.Length != 100) throw new ArgumentException("Profile data must be 100 bytes.");
|
||||
|
||||
PID = pid;
|
||||
Data = data;
|
||||
IpAddress = ip_address;
|
||||
}
|
||||
|
||||
// todo: encapsulate these so calculated fields are always correct
|
||||
public int PID;
|
||||
public byte[] Data; // 100 bytes
|
||||
public string IpAddress;
|
||||
|
||||
public Versions Version
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user