Add Thread-Safe Lists, and make all list access thread-safe

This commit is contained in:
Li 2022-08-31 20:31:07 +12:00
parent 900fe0d48a
commit 40c34ac030
24 changed files with 111 additions and 44 deletions

View file

@ -1,5 +1,5 @@
Package: hisp Package: hisp
Version: 1.7.121 Version: 1.7.123
Depends: coreutils,systemd,mariadb-server,libsqlite3-dev,zlib1g-dev,libicu-dev,libkrb5-dev Depends: coreutils,systemd,mariadb-server,libsqlite3-dev,zlib1g-dev,libicu-dev,libkrb5-dev
Maintainer: Li Maintainer: Li
Homepage: https://islehorse.com Homepage: https://islehorse.com

View file

@ -1,4 +1,5 @@
using System.Collections.Generic; using HISP.Server;
using System.Collections.Generic;
namespace HISP.Game namespace HISP.Game
{ {
public class AbuseReport public class AbuseReport

View file

@ -14,7 +14,7 @@ namespace HISP.Game
{ {
private static List<Arena> arenas = new List<Arena>(); private static List<Arena> arenas = new List<Arena>();
private List<ArenaEntry> entries; private ThreadSafeList<ArenaEntry> entries;
private Timer arenaTimeout; private Timer arenaTimeout;
public static int[] ExpRewards; public static int[] ExpRewards;
public int Id; public int Id;
@ -59,7 +59,7 @@ namespace HISP.Game
Slots = slots; Slots = slots;
Timeout = timeOut; Timeout = timeOut;
arenas.Add(this); arenas.Add(this);
entries = new List<ArenaEntry>(); entries = new ThreadSafeList<ArenaEntry>();
} }
public bool HaveAllPlayersCompleted() public bool HaveAllPlayersCompleted()

View file

@ -13,7 +13,7 @@ namespace HISP.Game.Events
public ThrowTracker(User thrower) public ThrowTracker(User thrower)
{ {
Thrower = thrower; Thrower = thrower;
thrownAt = new List<User>(); thrownAt = new ThreadSafeList<User>();
} }
public void AddThrownAt(User user) public void AddThrownAt(User user)
@ -21,7 +21,7 @@ namespace HISP.Game.Events
thrownAt.Add(user); thrownAt.Add(user);
} }
public User Thrower; public User Thrower;
private List<User> thrownAt; private ThreadSafeList<User> thrownAt;
public User[] ThrownAt public User[] ThrownAt
{ {
get get
@ -33,7 +33,7 @@ namespace HISP.Game.Events
public bool Active = false; public bool Active = false;
public const int REVENGE_TIMEOUT = 10; public const int REVENGE_TIMEOUT = 10;
private List<ThrowTracker> trackedThrows; private ThreadSafeList<ThrowTracker> trackedThrows;
private Timer revengeTimeout; private Timer revengeTimeout;
public ThrowTracker[] TrackedThrows public ThrowTracker[] TrackedThrows
{ {
@ -45,7 +45,7 @@ namespace HISP.Game.Events
public ModsRevenge() public ModsRevenge()
{ {
trackedThrows = new List<ThrowTracker>(); trackedThrows = new ThreadSafeList<ThrowTracker>();
Active = false; Active = false;
} }

View file

@ -97,11 +97,11 @@ namespace HISP.Game.Events
return participents.ToArray(); return participents.ToArray();
} }
} }
private List<Participent> participents; private ThreadSafeList<Participent> participents;
public RealTimeQuiz() public RealTimeQuiz()
{ {
participents = new List<Participent>(); participents = new ThreadSafeList<Participent>();
Questions = new QuizQuestion[8]; Questions = new QuizQuestion[8];
for(int i = 0; i < 8; i++) for(int i = 0; i < 8; i++)
{ {

View file

@ -181,7 +181,7 @@ namespace HISP.Game.Horse
Despawn(this); Despawn(this);
} }
private static List<WildHorse> wildHorses = new List<WildHorse>(); private static ThreadSafeList<WildHorse> wildHorses = new ThreadSafeList<WildHorse>();
public static WildHorse[] WildHorses public static WildHorse[] WildHorses
{ {
get get

View file

@ -8,7 +8,7 @@ namespace HISP.Game.Inventory
public class HorseInventory public class HorseInventory
{ {
private User baseUser; private User baseUser;
private List<HorseInstance> horsesList = new List<HorseInstance>(); private ThreadSafeList<HorseInstance> horsesList = new ThreadSafeList<HorseInstance>();
public HorseInstance[] HorseList public HorseInstance[] HorseList
{ {
get get

View file

@ -1,21 +1,20 @@
using System; using HISP.Game.Items;
using System.Collections.Generic; using HISP.Server;
using HISP.Game.Items;
namespace HISP.Game.Inventory namespace HISP.Game.Inventory
{ {
public class InventoryItem public class InventoryItem
{ {
public InventoryItem() public InventoryItem()
{ {
itemInstances = new List<ItemInstance>(); itemInstances = new ThreadSafeList<ItemInstance>();
Infinite = false; Infinite = false;
ItemId = 0; ItemId = 0;
} }
public int ItemId; public int ItemId;
public bool Infinite; public bool Infinite;
private List<ItemInstance> itemInstances; private ThreadSafeList<ItemInstance> itemInstances;
public void RemoveItem(ItemInstance itm) public void RemoveItem(ItemInstance itm)
{ {
itemInstances.Remove(itm); itemInstances.Remove(itm);

View file

@ -13,10 +13,10 @@ namespace HISP.Game.Inventory
public User BaseUser; public User BaseUser;
private List<InventoryItem> inventoryItems; private ThreadSafeList<InventoryItem> inventoryItems;
public PlayerInventory(User forUser) public PlayerInventory(User forUser)
{ {
inventoryItems = new List<InventoryItem>(); inventoryItems = new ThreadSafeList<InventoryItem>();
BaseUser = forUser; BaseUser = forUser;
ItemInstance[] instances = Database.GetPlayerInventory(BaseUser.Id).ToArray(); ItemInstance[] instances = Database.GetPlayerInventory(BaseUser.Id).ToArray();

View file

@ -10,7 +10,7 @@ namespace HISP.Game.Inventory
public class ShopInventory : IInventory public class ShopInventory : IInventory
{ {
private Shop baseShop; private Shop baseShop;
private List<InventoryItem> inventoryItems; private ThreadSafeList<InventoryItem> inventoryItems;
public int Count public int Count
{ {
get get
@ -21,7 +21,7 @@ namespace HISP.Game.Inventory
public ShopInventory(Shop shopkeeper) public ShopInventory(Shop shopkeeper)
{ {
baseShop = shopkeeper; baseShop = shopkeeper;
inventoryItems = new List<InventoryItem>(); inventoryItems = new ThreadSafeList<InventoryItem>();
} }
private void addItem(ItemInstance item, bool addToDatabase) private void addItem(ItemInstance item, bool addToDatabase)

View file

@ -8,7 +8,7 @@ namespace HISP.Game
public class Multiroom public class Multiroom
{ {
private static List<Multiroom> multirooms = new List<Multiroom>(); private static List<Multiroom> multirooms = new List<Multiroom>();
private List<User> joinedUsers = new List<User>(); private ThreadSafeList<User> joinedUsers = new ThreadSafeList<User>();
public int x; public int x;
public int y; public int y;

View file

@ -8,7 +8,7 @@ namespace HISP.Game.Services
{ {
public class Auction public class Auction
{ {
private static List<Auction> auctionRooms = new List<Auction>(); private static ThreadSafeList<Auction> auctionRooms = new ThreadSafeList<Auction>();
public static Auction[] AuctionRooms public static Auction[] AuctionRooms
{ {
get get
@ -20,7 +20,7 @@ namespace HISP.Game.Services
public Auction(int id) public Auction(int id)
{ {
RoomId = id; RoomId = id;
auctionEntries = new List<AuctionEntry>(); auctionEntries = new ThreadSafeList<AuctionEntry>();
Database.LoadAuctionRoom(this, RoomId); Database.LoadAuctionRoom(this, RoomId);
} }
@ -122,7 +122,7 @@ namespace HISP.Game.Services
public HorseInstance Horse; public HorseInstance Horse;
public int OwnerId; public int OwnerId;
private List<AuctionBid> bidders = new List<AuctionBid>(); private ThreadSafeList<AuctionBid> bidders = new ThreadSafeList<AuctionBid>();
public AuctionBid[] Bidders public AuctionBid[] Bidders
{ {
get get
@ -297,7 +297,7 @@ namespace HISP.Game.Services
auctionEntries.Add(entry); auctionEntries.Add(entry);
} }
private List<AuctionEntry> auctionEntries; private ThreadSafeList<AuctionEntry> auctionEntries;
public int RoomId; public int RoomId;
public AuctionEntry[] AuctionEntries public AuctionEntry[] AuctionEntries

View file

@ -17,7 +17,7 @@ namespace HISP.Game.SwfModules
public class DressupRoom public class DressupRoom
{ {
public int RoomId; public int RoomId;
private List<DressupPeice> dressupPeices; private ThreadSafeList<DressupPeice> dressupPeices;
public DressupPeice[] DressupPeices public DressupPeice[] DressupPeices
{ {
get get
@ -28,7 +28,7 @@ namespace HISP.Game.SwfModules
public DressupRoom(int roomId) public DressupRoom(int roomId)
{ {
RoomId = roomId; RoomId = roomId;
dressupPeices = new List<DressupPeice>(); dressupPeices = new ThreadSafeList<DressupPeice>();
DressupPeice[] peices = Database.LoadDressupRoom(this); DressupPeice[] peices = Database.LoadDressupRoom(this);
foreach (DressupPeice peice in peices) foreach (DressupPeice peice in peices)

View file

@ -57,7 +57,7 @@ namespace HISP.Game
private int count; private int count;
private User baseUser; private User baseUser;
} }
private List<TrackedItem> trackingItems = new List<TrackedItem>(); private ThreadSafeList<TrackedItem> trackingItems = new ThreadSafeList<TrackedItem>();
private User baseUser; private User baseUser;
public TrackedItem[] TrackingItems public TrackedItem[] TrackingItems
{ {

View file

@ -41,7 +41,7 @@ namespace HISP.Player
} }
private List<AwardEntry> awardsEarned; private ThreadSafeList<AwardEntry> awardsEarned;
private User baseUser; private User baseUser;
public AwardEntry[] AwardsEarned public AwardEntry[] AwardsEarned
{ {
@ -84,7 +84,7 @@ namespace HISP.Player
{ {
baseUser = user; baseUser = user;
int[] awards = Database.GetAwards(user.Id); int[] awards = Database.GetAwards(user.Id);
awardsEarned = new List<AwardEntry>(); awardsEarned = new ThreadSafeList<AwardEntry>();
foreach (int awardid in awards) foreach (int awardid in awards)
{ {

View file

@ -7,7 +7,7 @@ namespace HISP.Player
public class Friends public class Friends
{ {
private User baseUser; private User baseUser;
private List<int> list; private ThreadSafeList<int> list;
public int[] List public int[] List
{ {
get get
@ -36,7 +36,7 @@ namespace HISP.Player
public Friends(User user) public Friends(User user)
{ {
baseUser = user; baseUser = user;
list = new List<int>(); list = new ThreadSafeList<int>();
int[] friends = Database.GetBuddyList(user.Id); int[] friends = Database.GetBuddyList(user.Id);
foreach(int friendId in friends) foreach(int friendId in friends)

View file

@ -24,7 +24,7 @@ namespace HISP.Player
} }
private User baseUser; private User baseUser;
private List<HighscoreTableEntry> highScoreList = new List<HighscoreTableEntry>(); private ThreadSafeList<HighscoreTableEntry> highScoreList = new ThreadSafeList<HighscoreTableEntry>();
public Highscore(User user) public Highscore(User user)
{ {

View file

@ -9,7 +9,7 @@ namespace HISP.Player
public class Mailbox public class Mailbox
{ {
private User baseUser; private User baseUser;
private List<Mail> mails = new List<Mail>(); private ThreadSafeList<Mail> mails = new ThreadSafeList<Mail>();
public int MailCount public int MailCount
{ {
get get

View file

@ -6,10 +6,10 @@ namespace HISP.Player
public class MutedPlayers public class MutedPlayers
{ {
private User baseUser; private User baseUser;
private List<int> userIds; private ThreadSafeList<int> userIds;
public MutedPlayers(User BaseUser) public MutedPlayers(User BaseUser)
{ {
userIds = new List<int>(); userIds = new ThreadSafeList<int>();
baseUser = BaseUser; baseUser = BaseUser;
int[] userids = Database.GetMutedPlayers(BaseUser.Id); int[] userids = Database.GetMutedPlayers(BaseUser.Id);

View file

@ -5,7 +5,7 @@ namespace HISP.Player
{ {
public class PlayerQuests public class PlayerQuests
{ {
private List<TrackedQuest> trackedQuests = new List<TrackedQuest>(); private ThreadSafeList<TrackedQuest> trackedQuests = new ThreadSafeList<TrackedQuest>();
public User BaseUser; public User BaseUser;
public TrackedQuest[] QuestList public TrackedQuest[] QuestList
{ {

View file

@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.7.121.0")] [assembly: AssemblyVersion("1.7.123.0")]
[assembly: AssemblyFileVersion("1.7.121.0")] [assembly: AssemblyFileVersion("1.7.123.0")]

View file

@ -12,7 +12,7 @@ namespace HISP.Server
{ {
public class GameClient public class GameClient
{ {
private static List<GameClient> connectedClients = new List<GameClient>(); private static ThreadSafeList<GameClient> connectedClients = new ThreadSafeList<GameClient>();
public static GameClient[] ConnectedClients // Done to prevent Enumerator Changed errors. public static GameClient[] ConnectedClients // Done to prevent Enumerator Changed errors.
{ {
get get

View file

@ -0,0 +1,67 @@
using System.Collections;
using System.Collections.Generic;
using System.Threading;
namespace HISP.Server
{
public class ThreadSafeList<T> : List<T>
{
private Mutex listLock = new Mutex();
new public void AddRange(IEnumerable<T> collection)
{
listLock.WaitOne();
base.AddRange(collection);
listLock.ReleaseMutex();
}
new public void Add(T value)
{
listLock.WaitOne();
base.Add(value);
listLock.ReleaseMutex();
}
new public void Clear()
{
listLock.WaitOne();
base.Clear();
listLock.ReleaseMutex();
}
new public bool Contains(T value)
{
listLock.WaitOne();
bool test = base.Contains(value);
listLock.ReleaseMutex();
return test;
}
new public IEnumerator GetEnumerator()
{
listLock.WaitOne();
IEnumerator res = base.ToArray().GetEnumerator();
listLock.ReleaseMutex();
return res;
}
new public void Insert(int index, T value)
{
listLock.WaitOne();
base.Insert(index, value);
listLock.ReleaseMutex();
}
new public void Remove(T value)
{
listLock.WaitOne();
base.Remove(value);
listLock.ReleaseMutex();
}
new public void RemoveAt(int index)
{
listLock.WaitOne();
base.RemoveAt(index);
listLock.ReleaseMutex();
}
}
}

View file

@ -30,5 +30,5 @@ using System.Runtime.InteropServices;
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.7.121.0")] [assembly: AssemblyVersion("1.7.123.0")]
[assembly: AssemblyFileVersion("1.7.121.0")] [assembly: AssemblyFileVersion("1.7.123.0")]