Skip to content

Commit 5510231

Browse files
committed
Limit New Accounts per day total and per day.
1 parent 7592d98 commit 5510231

4 files changed

Lines changed: 71 additions & 5 deletions

File tree

openlife/server/Connection.hx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class Connection {
2525

2626
public var sock:Socket;
2727
public var sendFrame = false;
28+
public var clientIp:String = ''; // Client IP for account limiting
2829

2930
var server:Server;
3031
var tag:ServerTag;
@@ -41,7 +42,10 @@ class Connection {
4142
var version = ObjectData.dataVersionNumber;
4243

4344
// if it is an AI there is no sock
44-
if (sock != null) send(SERVER_INFO, ["0/0", challenge, '$version']);
45+
if (sock != null) {
46+
clientIp = sock.peer().host.toString(); // Get client IP for account limiting
47+
send(SERVER_INFO, ["0/0", challenge, '$version']);
48+
}
4549
}
4650

4751
public function isAi():Bool {
@@ -93,7 +97,13 @@ class Connection {
9397

9498
trace('login2: ${account_key_hash}');
9599

96-
this.playerAccount = PlayerAccount.GetOrCreatePlayerAccount(email, account_key_hash);
100+
this.playerAccount = PlayerAccount.GetOrCreatePlayerAccount(email, account_key_hash, 0, clientIp);
101+
if (this.playerAccount == null) {
102+
trace('login: ${account_key_hash} REJECTED! Account limit reached for IP ${clientIp}');
103+
send(REJECTED);
104+
if (sock != null) sock.close();
105+
return;
106+
}
97107
this.player = GlobalPlayerInstance.CreateNewHumanPlayer(this);
98108

99109
Macro.exception(initConnection(this.player, this.playerAccount));
@@ -123,7 +133,13 @@ class Connection {
123133
trace('rlogin2: ${account_key_hash}');
124134
// GlobalPlayerInstance.AcquireMutex();
125135

126-
this.playerAccount = PlayerAccount.GetOrCreatePlayerAccount(email, account_key_hash);
136+
this.playerAccount = PlayerAccount.GetOrCreatePlayerAccount(email, account_key_hash, 0, clientIp);
137+
if (this.playerAccount == null) {
138+
trace('rlogin: ${account_key_hash} REJECTED! Account limit reached for IP ${clientIp}');
139+
send(REJECTED);
140+
if (sock != null) sock.close();
141+
return;
142+
}
127143
var lastLivingPlayer = playerAccount.getLastLivingPlayer();
128144

129145
if (lastLivingPlayer != null) {

openlife/server/PlayerAccount.hx

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ class PlayerAccount {
1212
public static var AllPlayerAccountsById = new Map<Int, PlayerAccount>();
1313
public static var AccountIdIndex:Int = 1;
1414

15+
// Account limiting - anti spam
16+
public static var newAccountsTodayPerIp = new Map<String, Int>(); // IP -> count
17+
public static var totalNewAccountsToday:Int = 0;
18+
public static var lastAccountResetTime:Float = 0;
19+
1520
// saved
1621
public var id:Int;
1722
public var isAi:Bool = false;
@@ -35,7 +40,6 @@ class PlayerAccount {
3540
public var scoreEntries = new Array<ScoreEntry>(); // is used to store prestige boni / mali
3641
public var displayClosePlayers:Bool = true;
3742
public var displayYum:Bool = true;
38-
3943
// not saved
4044
public var graves = new Array<ObjectHelper>();
4145

@@ -47,10 +51,31 @@ class PlayerAccount {
4751

4852
private function new() {}
4953

50-
public static function GetOrCreatePlayerAccount(email:String, account_key_hash:String, id:Int = 0):PlayerAccount {
54+
// if Ip is not set there is no limit to account generation
55+
public static function GetOrCreatePlayerAccount(email:String, account_key_hash:String, id:Int = 0, clientIp:String = ''):PlayerAccount {
56+
var checkLimit = clientIp != '';
5157
var account = AllPlayerAccountsByEmail[email];
5258
if (account != null) return account;
5359

60+
// Check if account limit reached
61+
if (checkLimit) {
62+
// Reset daily counts if it's a new day
63+
ResetDailyAccountCounts();
64+
65+
// Check IP-specific limit
66+
var ipCount = newAccountsTodayPerIp[clientIp];
67+
if (ipCount != null && ipCount >= ServerSettings.NewAccountsPerIpPerDay) {
68+
trace('PlayerAccount: WARNING: IP account limit reached for $clientIp ($ipCount/${ServerSettings.NewAccountsPerIpPerDay} per day)');
69+
return null;
70+
}
71+
72+
// Check total server-wide limit
73+
if (totalNewAccountsToday >= ServerSettings.TotalNewAccountsPerDay) {
74+
trace('PlayerAccount: WARNING: Total daily account limit reached ($totalNewAccountsToday/${ServerSettings.TotalNewAccountsPerDay})');
75+
return null;
76+
}
77+
}
78+
5479
account = new PlayerAccount();
5580
account.id = id > 0 ? id : AccountIdIndex++;
5681
account.email = email;
@@ -59,11 +84,32 @@ class PlayerAccount {
5984
AllPlayerAccountsByEmail[account.email] = account;
6085
AllPlayerAccountsById[account.id] = account;
6186

87+
// Track new account creation
88+
if (checkLimit) {
89+
totalNewAccountsToday++;
90+
91+
var ipCount = newAccountsTodayPerIp[clientIp];
92+
newAccountsTodayPerIp[clientIp] = (ipCount != null ? ipCount : 0) + 1;
93+
trace('PlayerAccount: New account created: ${account.id} from IP $clientIp (today: $totalNewAccountsToday total, IP: ${newAccountsTodayPerIp[clientIp]})');
94+
}
95+
6296
// trace('New account: ${id}-->${account.id} $email');
6397

6498
return account;
6599
}
66100

101+
public static function ResetDailyAccountCounts() {
102+
var now = Date.now().getTime();
103+
var oneDayInMs:Float = 86400000; // 24 * 60 * 60 * 1000
104+
105+
if (now - lastAccountResetTime >= oneDayInMs) {
106+
newAccountsTodayPerIp = new Map<String, Int>();
107+
totalNewAccountsToday = 0;
108+
lastAccountResetTime = now;
109+
trace('PlayerAccount: Daily account counts reset for day ${Date.now()}');
110+
}
111+
}
112+
67113
public static function GetPlayerAccountById(id:Int):PlayerAccount {
68114
return AllPlayerAccountsById[id];
69115
}

openlife/settings/ServerSettings.hx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ class ServerSettings {
5151
public static var DebugCreateOldPath:Bool = false; // To compare new pathing method with old
5252
public static var DebugWritePathToFile:Bool = false; // wriths path map to SaveFiles/paths.txt
5353

54+
// Account limiting
55+
public static var NewAccountsPerIpPerDay:Int = 3; // Max new accounts per IP per day
56+
public static var TotalNewAccountsPerDay:Int = 20; // Total new accounts server-wide per day
57+
5458
// Save / Load
5559
public static var saveToDisk = true;
5660
public static var SavePlayers = true;

server.hl

2.62 KB
Binary file not shown.

0 commit comments

Comments
 (0)