Use safer method for retrieving next player id.

This commit is contained in:
UnknownShadow200 2016-08-02 18:27:21 +10:00
parent b297191501
commit 22003a321c
3 changed files with 26 additions and 22 deletions

View File

@ -372,7 +372,7 @@ namespace MCGalaxy {
group = foundGrp;
Loading = true;
if (disconnected) return;
id = FreeId();
id = NextFreeId();
if (type != 0x42)
CompleteLoginProcess();
@ -483,7 +483,7 @@ namespace MCGalaxy {
SendBlockchange(0, 0, 0, 0);
timeLogged = DateTime.Now;
lastLogin = DateTime.Now;
p.time = new TimeSpan(0, 0, 0, 1);
time = new TimeSpan(0, 0, 0, 1);
DataTable playerDb = Database.Fill("SELECT * FROM Players WHERE Name=@0", name);
if (playerDb.Rows.Count == 0)

View File

@ -380,24 +380,24 @@ catch { }*/
[Obsolete("Use PlayerInfo.FindNick(name)")]
public static Player FindNick(string name) { return PlayerInfo.FindNick(null, name); }
static byte FreeId() {
/*
for (byte i = 0; i < 255; i++)
{
foreach (Player p in players)
{
if (p.id == i) { goto Next; }
} return i;
Next: continue;
} unchecked { return 0xFF; }*/
unsafe static byte NextFreeId() {
byte* used = stackalloc byte[256];
for (int i = 0; i < 256; i++)
used[i] = 0;
for ( byte i = 0; i < 255; i++ ) {
bool used = PlayerInfo.players.Any(p => p.id == i);
if ( !used )
return i;
// Lock to ensure that no two players can end up with the same playerid
lock (PlayerInfo.Online.locker) {
Player[] players = PlayerInfo.Online.Items;
for (int i = 0; i < players.Length; i++) {
byte id = players[i].id;
used[id] = 1;
}
}
return (byte)1;
for (byte i = 0; i < 255; i++ ) {
if (used[i] == 0) return i;
}
return 1;
}
public static bool ValidName(string name) {

View File

@ -19,17 +19,21 @@ using System;
using System.Collections.Generic;
namespace MCGalaxy {
public sealed class VolatileArray<T> {
public List<T> list;
/// <remarks> Note this field is highly volatile, you should cache references to it. </remarks>
public volatile T[] Items = new T[0];
/// <summary> Returns the number of items in this array. </summary>
public int Count { get { return Items.Length; } }
readonly object locker = new object();
/// <summary> Object used to sychronise Add/Remove calls to this array. </summary>
/// <remarks> When locking on this object from external code, you should try
/// to minimise the amount of time the object is locked for. </remarks>
public readonly object locker = new object();
public List<T> list;
readonly bool useList;
public VolatileArray(bool useList) {