Files
gameauthapi/Services/LocationService.cs
T

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);
}
}