104 lines
4.0 KiB
C#
104 lines
4.0 KiB
C#
using System.Threading.Tasks;
|
|
using System.Collections.Generic;
|
|
using GameAuthApi.Models;
|
|
using Microsoft.Extensions.Configuration;
|
|
using MongoDB.Bson;
|
|
using MongoDB.Driver;
|
|
|
|
namespace GameAuthApi.Services;
|
|
|
|
public class LocationService
|
|
{
|
|
private readonly IMongoCollection<Location> _locations;
|
|
|
|
public LocationService(IConfiguration config)
|
|
{
|
|
var client = new MongoClient(config["MongoDB:ConnectionString"]);
|
|
var db = client.GetDatabase(config["MongoDB:DatabaseName"]);
|
|
_locations = db.GetCollection<Location>("Locations");
|
|
}
|
|
|
|
public virtual async Task<Location> GetByIdAsync(string id)
|
|
{
|
|
if (!ObjectId.TryParse(id, out _))
|
|
return null; // prevent crash if id is invalid
|
|
|
|
return await _locations.Find(x => x.Id == id).FirstOrDefaultAsync();
|
|
}
|
|
|
|
public virtual async Task CreateAsync(Location loc) =>
|
|
await _locations.InsertOneAsync(loc);
|
|
|
|
public virtual async Task DeleteAsync(string id) =>
|
|
await _locations.DeleteOneAsync(loc => loc.Id == id);
|
|
|
|
public virtual async Task<List<Location>> GetByTypeAsync(string type)
|
|
{
|
|
return await _locations.Find(l => l.LocationType == type).ToListAsync();
|
|
}
|
|
|
|
public virtual async Task DeleteByTypeAsync(string type) =>
|
|
await _locations.DeleteManyAsync(l => l.LocationType == type);
|
|
|
|
public virtual async Task DeleteAllAsync() =>
|
|
await _locations.DeleteManyAsync(_ => true);
|
|
public virtual async Task UpdateAsync(Location loc) =>
|
|
await _locations.ReplaceOneAsync(l => l.Id == loc.Id, loc);
|
|
|
|
public virtual async Task AddPlayerToLocationAsync(string locationId, string playerId)
|
|
{
|
|
var update = Builders<Location>.Update.AddToSet(l => l.Players, playerId);
|
|
await _locations.UpdateOneAsync(l => l.Id == locationId, update);
|
|
}
|
|
|
|
public virtual async Task<Location> GetByCoordinatesAsync(int x, int y, int z)
|
|
{
|
|
return await _locations.Find(loc => loc.X == x && loc.Y == y && loc.Z == z).FirstOrDefaultAsync();
|
|
}
|
|
|
|
public virtual async Task<Location> GetSpawnLocationAsync()
|
|
{
|
|
return await _locations.Find(loc => loc.X == 0 && loc.Y == 0).FirstOrDefaultAsync();
|
|
}
|
|
|
|
public virtual async Task RemovePlayerFromLocationAsync(string locationId, string playerId)
|
|
{
|
|
var update = Builders<Location>.Update.Pull(l => l.Players, playerId);
|
|
await _locations.UpdateOneAsync(l => l.Id == locationId, update);
|
|
}
|
|
|
|
public virtual async Task AddItemToLocationAsync(string locationId, string itemId)
|
|
{
|
|
if (!ObjectId.TryParse(locationId, out _) || !ObjectId.TryParse(itemId, out _))
|
|
return;
|
|
|
|
var idFilter = Builders<Location>.Filter.Eq(l => l.Id, locationId);
|
|
|
|
// if the Content array is null, initialize it first
|
|
// use a raw BsonDocument filter to avoid casting BsonNull to an ObjectId
|
|
var nullFilter = idFilter & new BsonDocument("Content", BsonNull.Value);
|
|
var initArray = Builders<Location>.Update.Set(l => l.Content, new List<string>());
|
|
await _locations.UpdateOneAsync(nullFilter, initArray);
|
|
|
|
var update = Builders<Location>.Update.Push(l => l.Content, itemId);
|
|
await _locations.UpdateOneAsync(idFilter, update);
|
|
}
|
|
|
|
public virtual async Task RemoveItemFromLocationAsync(string locationId, string itemId)
|
|
{
|
|
if (!ObjectId.TryParse(locationId, out _) || !ObjectId.TryParse(itemId, out _))
|
|
return;
|
|
|
|
// check that the Content array exists by using a raw BsonDocument filter
|
|
var filter = Builders<Location>.Filter.Eq(l => l.Id, locationId) & new BsonDocument("Content", new BsonDocument("$ne", BsonNull.Value));
|
|
var update = Builders<Location>.Update.Pull(l => l.Content, itemId);
|
|
await _locations.UpdateOneAsync(filter, update);
|
|
}
|
|
|
|
public virtual async Task ClearAllItemsAsync()
|
|
{
|
|
var update = Builders<Location>.Update.Set(l => l.Content, new List<string>());
|
|
await _locations.UpdateManyAsync(_ => true, update);
|
|
}
|
|
}
|