mirror of
https://github.com/simtactics/mysimulation.git
synced 2025-07-04 13:47:04 -04:00
Removed NioTSO client and server
- NioTSO client isn't needed because we're using RayLib - Added FreeSO's API server to handle most backend operations
This commit is contained in:
parent
f12ba1502b
commit
22191ce648
591 changed files with 53264 additions and 3362 deletions
12
server/FSO.Server.Database/DA/AbstractSqlDA.cs
Executable file
12
server/FSO.Server.Database/DA/AbstractSqlDA.cs
Executable file
|
@ -0,0 +1,12 @@
|
|||
namespace FSO.Server.Database.DA
|
||||
{
|
||||
public class AbstractSqlDA
|
||||
{
|
||||
protected ISqlContext Context;
|
||||
|
||||
public AbstractSqlDA(ISqlContext context)
|
||||
{
|
||||
this.Context = context;
|
||||
}
|
||||
}
|
||||
}
|
10
server/FSO.Server.Database/DA/AuthTickets/AuthTicket.cs
Executable file
10
server/FSO.Server.Database/DA/AuthTickets/AuthTicket.cs
Executable file
|
@ -0,0 +1,10 @@
|
|||
namespace FSO.Server.Database.DA.AuthTickets
|
||||
{
|
||||
public class AuthTicket
|
||||
{
|
||||
public string ticket_id { get; set; }
|
||||
public uint user_id { get; set; }
|
||||
public uint date { get; set; }
|
||||
public string ip { get; set; }
|
||||
}
|
||||
}
|
10
server/FSO.Server.Database/DA/AuthTickets/IAuthTickets.cs
Executable file
10
server/FSO.Server.Database/DA/AuthTickets/IAuthTickets.cs
Executable file
|
@ -0,0 +1,10 @@
|
|||
namespace FSO.Server.Database.DA.AuthTickets
|
||||
{
|
||||
public interface IAuthTickets
|
||||
{
|
||||
void Create(AuthTicket ticket);
|
||||
AuthTicket Get(string id);
|
||||
void Delete(string id);
|
||||
void Purge(uint time);
|
||||
}
|
||||
}
|
33
server/FSO.Server.Database/DA/AuthTickets/SqlAuthTickets.cs
Executable file
33
server/FSO.Server.Database/DA/AuthTickets/SqlAuthTickets.cs
Executable file
|
@ -0,0 +1,33 @@
|
|||
using System.Linq;
|
||||
using Dapper;
|
||||
|
||||
namespace FSO.Server.Database.DA.AuthTickets
|
||||
{
|
||||
public class SqlAuthTickets : AbstractSqlDA, IAuthTickets
|
||||
{
|
||||
public SqlAuthTickets(ISqlContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public void Create(AuthTicket ticket)
|
||||
{
|
||||
Context.Connection.Execute("INSERT INTO fso_auth_tickets VALUES (@ticket_id, @user_id, @date, @ip)", ticket);
|
||||
}
|
||||
|
||||
public void Delete(string id)
|
||||
{
|
||||
Context.Connection.Execute("DELETE FROM fso_auth_tickets WHERE ticket_id = @ticket_id", new { ticket_id = id });
|
||||
}
|
||||
|
||||
public AuthTicket Get(string id)
|
||||
{
|
||||
return
|
||||
Context.Connection.Query<AuthTicket>("SELECT * FROM fso_auth_tickets WHERE ticket_id = @ticket_id", new { ticket_id = id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public void Purge(uint time)
|
||||
{
|
||||
Context.Connection.Execute("DELETE FROM fso_auth_tickets WHERE date < @time", new { time = time });
|
||||
}
|
||||
}
|
||||
}
|
17
server/FSO.Server.Database/DA/AvatarClaims/DbAvatarClaim.cs
Executable file
17
server/FSO.Server.Database/DA/AvatarClaims/DbAvatarClaim.cs
Executable file
|
@ -0,0 +1,17 @@
|
|||
namespace FSO.Server.Database.DA.AvatarClaims
|
||||
{
|
||||
public class DbAvatarClaim
|
||||
{
|
||||
public int avatar_claim_id { get; set; }
|
||||
public uint avatar_id { get; set; }
|
||||
public string owner { get; set; }
|
||||
public uint location { get; set; }
|
||||
}
|
||||
public class DbAvatarActive
|
||||
{
|
||||
public uint avatar_id { get; set; }
|
||||
public string name { get; set; }
|
||||
public byte privacy_mode { get; set; }
|
||||
public uint location { get; set; }
|
||||
}
|
||||
}
|
21
server/FSO.Server.Database/DA/AvatarClaims/IAvatarClaims.cs
Executable file
21
server/FSO.Server.Database/DA/AvatarClaims/IAvatarClaims.cs
Executable file
|
@ -0,0 +1,21 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.AvatarClaims
|
||||
{
|
||||
public interface IAvatarClaims
|
||||
{
|
||||
DbAvatarClaim Get(int id);
|
||||
IEnumerable<DbAvatarClaim> GetAll();
|
||||
IEnumerable<DbAvatarActive> GetAllActiveAvatars();
|
||||
int? GetAllActiveAvatarsCount();
|
||||
DbAvatarClaim GetByAvatarID(uint id);
|
||||
IEnumerable<DbAvatarClaim> GetAllByOwner(string owner);
|
||||
|
||||
int? TryCreate(DbAvatarClaim claim);
|
||||
bool Claim(int id, string previousOwner, string newOwner, uint location);
|
||||
void RemoveRemaining(string previousOwner, uint location);
|
||||
|
||||
void Delete(int id, string owner);
|
||||
void DeleteAll(string owner);
|
||||
}
|
||||
}
|
84
server/FSO.Server.Database/DA/AvatarClaims/SqlAvatarClaims.cs
Executable file
84
server/FSO.Server.Database/DA/AvatarClaims/SqlAvatarClaims.cs
Executable file
|
@ -0,0 +1,84 @@
|
|||
using Dapper;
|
||||
using MySql.Data.MySqlClient;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace FSO.Server.Database.DA.AvatarClaims
|
||||
{
|
||||
public class SqlAvatarClaims : AbstractSqlDA, IAvatarClaims
|
||||
{
|
||||
public SqlAvatarClaims(ISqlContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public bool Claim(int id, string previousOwner, string newOwner, uint location)
|
||||
{
|
||||
try
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_avatar_claims SET owner = @owner, location = @location WHERE avatar_claim_id = @claim_id AND owner = @previous_owner", new { claim_id = (int)id, previous_owner = previousOwner, owner = newOwner, location = location });
|
||||
var newClaim = Context.Connection.Query<DbAvatarClaim>("SELECT * FROM fso_avatar_claims WHERE avatar_claim_id = @claim_id AND owner = @owner", new { claim_id = (int)id, owner = newOwner }).FirstOrDefault();
|
||||
return newClaim != null;
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveRemaining(string previousOwner, uint location)
|
||||
{
|
||||
Context.Connection.Query("DELETE FROM fso_avatar_claims WHERE location = @location AND owner = @previous_owner", new { previous_owner = previousOwner, location = location });
|
||||
}
|
||||
|
||||
|
||||
public void Delete(int id, string owner)
|
||||
{
|
||||
Context.Connection.Query("DELETE FROM fso_avatar_claims WHERE owner = @owner AND avatar_claim_id = @claim_id", new { owner = owner, claim_id = (int)id });
|
||||
}
|
||||
|
||||
public void DeleteAll(string owner)
|
||||
{
|
||||
Context.Connection.Query("DELETE FROM fso_avatar_claims WHERE owner = @owner", new { owner = owner });
|
||||
}
|
||||
|
||||
public DbAvatarClaim Get(int id)
|
||||
{
|
||||
return Context.Connection.Query<DbAvatarClaim>("SELECT * FROM fso_avatar_claims WHERE avatar_claim_id = @claim_id", new { claim_id = (int)id }).FirstOrDefault();
|
||||
}
|
||||
public IEnumerable<DbAvatarClaim> GetAll()
|
||||
{
|
||||
return Context.Connection.Query<DbAvatarClaim>("SELECT * FROM fso_avatar_claims");
|
||||
}
|
||||
public IEnumerable<DbAvatarActive> GetAllActiveAvatars()
|
||||
{
|
||||
return Context.Connection.Query<DbAvatarActive>("SELECT b.*, a.location FROM fso.fso_avatar_claims as a "+
|
||||
"inner join fso.fso_avatars as b ON a.avatar_id = b.avatar_id;");
|
||||
}
|
||||
public int? GetAllActiveAvatarsCount()
|
||||
{
|
||||
return Context.Connection.Query<int>("SELECT COUNT(*) FROM fso_avatar_claims").FirstOrDefault();
|
||||
}
|
||||
public DbAvatarClaim GetByAvatarID(uint id)
|
||||
{
|
||||
return Context.Connection.Query<DbAvatarClaim>("SELECT * FROM fso_avatar_claims WHERE avatar_id = @id", new { id = id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public IEnumerable<DbAvatarClaim> GetAllByOwner(string owner)
|
||||
{
|
||||
return Context.Connection.Query<DbAvatarClaim>("SELECT * FROM fso_avatar_claims WHERE owner = @owner", new { owner = owner });
|
||||
}
|
||||
|
||||
public int? TryCreate(DbAvatarClaim claim)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Context.Connection.Query<int>("INSERT INTO fso_avatar_claims (avatar_id, owner, location) " +
|
||||
" VALUES (@avatar_id, @owner, @location); SELECT LAST_INSERT_ID();", claim).First();
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
70
server/FSO.Server.Database/DA/Avatars/DbAvatar.cs
Executable file
70
server/FSO.Server.Database/DA/Avatars/DbAvatar.cs
Executable file
|
@ -0,0 +1,70 @@
|
|||
namespace FSO.Server.Database.DA.Avatars
|
||||
{
|
||||
public class DbAvatar
|
||||
{
|
||||
public uint avatar_id { get; set; }
|
||||
public int shard_id { get; set; }
|
||||
public uint user_id { get; set; }
|
||||
public string name { get; set; }
|
||||
public DbAvatarGender gender { get; set; }
|
||||
public uint date { get; set; }
|
||||
public byte skin_tone { get; set; }
|
||||
public ulong head { get; set; }
|
||||
public ulong body { get; set; }
|
||||
public string description { get; set; }
|
||||
public int budget { get; set; }
|
||||
public byte privacy_mode { get; set; }
|
||||
|
||||
//lot persist state beyond this point (very mutable)
|
||||
|
||||
public byte[] motive_data { get; set; }
|
||||
//locks
|
||||
|
||||
public byte skilllock { get; set; } //number of skill locks we had at last avatar save. this is usually handled by data service.
|
||||
public ushort lock_mechanical { get; set; }
|
||||
public ushort lock_cooking { get; set; }
|
||||
public ushort lock_charisma { get; set; }
|
||||
public ushort lock_logic { get; set; }
|
||||
public ushort lock_body { get; set; }
|
||||
public ushort lock_creativity { get; set; }
|
||||
//skills
|
||||
public ushort skill_mechanical { get; set; }
|
||||
public ushort skill_cooking { get; set; }
|
||||
public ushort skill_charisma { get; set; }
|
||||
public ushort skill_logic { get; set; }
|
||||
public ushort skill_body { get; set; }
|
||||
public ushort skill_creativity { get; set; }
|
||||
|
||||
public ulong body_swimwear { get; set; }
|
||||
public ulong body_sleepwear { get; set; }
|
||||
public ulong body_current { get; set; }
|
||||
|
||||
public ushort current_job { get; set; }
|
||||
public ushort is_ghost { get; set; }
|
||||
public ushort ticker_death { get; set; }
|
||||
public ushort ticker_gardener { get; set; }
|
||||
public ushort ticker_maid { get; set; }
|
||||
public ushort ticker_repairman { get; set; }
|
||||
|
||||
public byte moderation_level { get; set; }
|
||||
public uint? custom_guid { get; set; }
|
||||
public uint move_date { get; set; }
|
||||
public uint name_date { get; set; }
|
||||
public int? mayor_nhood { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class DbTransactionResult
|
||||
{
|
||||
public bool success { get; set; }
|
||||
public int source_budget { get; set; }
|
||||
public int dest_budget { get; set; }
|
||||
public int amount { get; set; }
|
||||
}
|
||||
|
||||
public enum DbAvatarGender
|
||||
{
|
||||
male,
|
||||
female
|
||||
}
|
||||
}
|
22
server/FSO.Server.Database/DA/Avatars/DbAvatarSummary.cs
Executable file
22
server/FSO.Server.Database/DA/Avatars/DbAvatarSummary.cs
Executable file
|
@ -0,0 +1,22 @@
|
|||
namespace FSO.Server.Database.DA.Avatars
|
||||
{
|
||||
public class DbAvatarSummary
|
||||
{
|
||||
//fso_avatar data
|
||||
public uint avatar_id { get; set; }
|
||||
public int shard_id { get; set; }
|
||||
public uint user_id { get; set; }
|
||||
public string name { get; set; }
|
||||
public DbAvatarGender gender { get; set; }
|
||||
public uint date { get; set; }
|
||||
public byte skin_tone { get; set; }
|
||||
public ulong head { get; set; }
|
||||
public ulong body { get; set; }
|
||||
public string description { get; set; }
|
||||
|
||||
//fso_lots
|
||||
public uint? lot_id { get; set; }
|
||||
public uint? lot_location { get; set; }
|
||||
public string lot_name { get; set; }
|
||||
}
|
||||
}
|
12
server/FSO.Server.Database/DA/Avatars/DbJobLevel.cs
Executable file
12
server/FSO.Server.Database/DA/Avatars/DbJobLevel.cs
Executable file
|
@ -0,0 +1,12 @@
|
|||
namespace FSO.Server.Database.DA.Avatars
|
||||
{
|
||||
public class DbJobLevel
|
||||
{
|
||||
public uint avatar_id { get; set; }
|
||||
public ushort job_type { get; set; }
|
||||
public ushort job_experience { get; set; }
|
||||
public ushort job_level { get; set; }
|
||||
public ushort job_sickdays { get; set; }
|
||||
public ushort job_statusflags { get; set; }
|
||||
}
|
||||
}
|
51
server/FSO.Server.Database/DA/Avatars/IAvatars.cs
Executable file
51
server/FSO.Server.Database/DA/Avatars/IAvatars.cs
Executable file
|
@ -0,0 +1,51 @@
|
|||
using FSO.Server.Database.DA.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Avatars
|
||||
{
|
||||
public interface IAvatars
|
||||
{
|
||||
uint Create(DbAvatar avatar);
|
||||
|
||||
DbAvatar Get(uint id);
|
||||
List<DbAvatar> GetMultiple(uint[] id);
|
||||
bool Delete(uint id);
|
||||
int GetPrivacyMode(uint id);
|
||||
int GetModerationLevel(uint id);
|
||||
DbJobLevel GetCurrentJobLevel(uint avatar_id);
|
||||
List<DbJobLevel> GetJobLevels(uint avatar_id);
|
||||
IEnumerable<DbAvatar> All();
|
||||
IEnumerable<DbAvatar> All(int shard_id);
|
||||
PagedList<DbAvatar> AllByPage(int shard_id, int offset, int limit, string orderBy);
|
||||
List<uint> GetLivingInNhood(uint nhood_id);
|
||||
List<AvatarRating> GetPossibleCandidatesNhood(uint nhood_id);
|
||||
|
||||
List<DbAvatar> GetByUserId(uint user_id);
|
||||
List<DbAvatarSummary> GetSummaryByUserId(uint user_id);
|
||||
|
||||
int GetOtherLocks(uint avatar_id, string except);
|
||||
|
||||
int GetBudget(uint avatar_id);
|
||||
DbTransactionResult Transaction(uint source_id, uint avatar_id, int amount, short reason);
|
||||
DbTransactionResult Transaction(uint source_id, uint avatar_id, int amount, short reason, Func<bool> transactionInject);
|
||||
DbTransactionResult TestTransaction(uint source_id, uint avatar_id, int amount, short reason);
|
||||
|
||||
void UpdateDescription(uint id, string description);
|
||||
void UpdatePrivacyMode(uint id, byte privacy);
|
||||
void UpdateAvatarLotSave(uint id, DbAvatar avatar);
|
||||
void UpdateAvatarJobLevel(DbJobLevel jobLevel);
|
||||
void UpdateMoveDate(uint id, uint date);
|
||||
void UpdateMayorNhood(uint id, uint? nhood);
|
||||
|
||||
List<DbAvatar> SearchExact(int shard_id, string name, int limit);
|
||||
List<DbAvatar> SearchWildcard(int shard_id, string name, int limit);
|
||||
}
|
||||
|
||||
public class AvatarRating
|
||||
{
|
||||
public uint avatar_id { get; set; }
|
||||
public string name { get; set; }
|
||||
public float? rating { get; set; }
|
||||
}
|
||||
}
|
401
server/FSO.Server.Database/DA/Avatars/SqlAvatars.cs
Executable file
401
server/FSO.Server.Database/DA/Avatars/SqlAvatars.cs
Executable file
|
@ -0,0 +1,401 @@
|
|||
using Dapper;
|
||||
using FSO.Server.Database.DA.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace FSO.Server.Database.DA.Avatars
|
||||
{
|
||||
public class SqlAvatars : AbstractSqlDA, IAvatars
|
||||
{
|
||||
public SqlAvatars(ISqlContext context) : base(context){
|
||||
}
|
||||
public PagedList<DbAvatar> AllByPage(int shard_id,int offset = 1, int limit = 100, string orderBy = "avatar_id")
|
||||
{
|
||||
var total = Context.Connection.Query<int>("SELECT COUNT(*) FROM fso_avatars WHERE shard_id = @shard_id",new { shard_id = shard_id }).FirstOrDefault();
|
||||
var results = Context.Connection.Query<DbAvatar>("SELECT * FROM fso_avatars WHERE shard_id = @shard_id ORDER BY @order DESC LIMIT @offset, @limit", new { shard_id = shard_id, order = orderBy, offset = offset, limit = limit });
|
||||
return new PagedList<DbAvatar>(results, offset, total);
|
||||
}
|
||||
|
||||
public IEnumerable<DbAvatar> All()
|
||||
{
|
||||
return Context.Connection.Query<DbAvatar>("SELECT * FROM fso_avatars");
|
||||
}
|
||||
|
||||
public IEnumerable<DbAvatar> All(int shard_id){
|
||||
return Context.Connection.Query<DbAvatar>("SELECT * FROM fso_avatars WHERE shard_id = @shard_id", new { shard_id = shard_id });
|
||||
}
|
||||
|
||||
public List<uint> GetLivingInNhood(uint neigh_id)
|
||||
{
|
||||
return Context.Connection.Query<uint>("SELECT avatar_id FROM fso_roommates r JOIN fso_lots l ON r.lot_id = l.lot_id "
|
||||
+ "WHERE neighborhood_id = @neigh_id", new { neigh_id = neigh_id }).ToList();
|
||||
}
|
||||
|
||||
public List<AvatarRating> GetPossibleCandidatesNhood(uint neigh_id)
|
||||
{
|
||||
return Context.Connection.Query<AvatarRating>("SELECT r.avatar_id, a.name, AVG(CAST(v.rating as DECIMAL(10,6))) AS rating " +
|
||||
"FROM (fso_roommates r JOIN fso_lots l ON r.lot_id = l.lot_id) " +
|
||||
"LEFT JOIN fso_mayor_ratings v ON v.to_avatar_id = r.avatar_id " +
|
||||
"JOIN fso_avatars a ON r.avatar_id = a.avatar_id " +
|
||||
"WHERE l.neighborhood_id = @neigh_id " +
|
||||
"GROUP BY avatar_id", new { neigh_id = neigh_id }).ToList();
|
||||
}
|
||||
|
||||
public DbAvatar Get(uint id){
|
||||
return Context.Connection.Query<DbAvatar>("SELECT * FROM fso_avatars WHERE avatar_id = @id", new { id = id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public bool Delete(uint id)
|
||||
{
|
||||
return Context.Connection.Execute("DELETE FROM fso_avatars WHERE avatar_id = @id", new { id = id }) > 0;
|
||||
}
|
||||
|
||||
public int GetPrivacyMode(uint id)
|
||||
{
|
||||
return Context.Connection.Query<int>("SELECT privacy_mode FROM fso_avatars WHERE avatar_id = @id", new { id = id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public int GetModerationLevel(uint id)
|
||||
{
|
||||
return Context.Connection.Query<int>("SELECT moderation_level FROM fso_avatars WHERE avatar_id = @id", new { id = id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public uint Create(DbAvatar avatar)
|
||||
{
|
||||
return (uint)Context.Connection.Query<int>("INSERT INTO fso_avatars (shard_id, user_id, name, " +
|
||||
"gender, date, skin_tone, head, body, description, budget, moderation_level, " +
|
||||
" body_swimwear, body_sleepwear) " +
|
||||
" VALUES (@shard_id, @user_id, @name, @gender, @date, " +
|
||||
" @skin_tone, @head, @body, @description, @budget, @moderation_level, "+
|
||||
" @body_swimwear, @body_sleepwear); SELECT LAST_INSERT_ID();", new
|
||||
{
|
||||
shard_id = avatar.shard_id,
|
||||
user_id = avatar.user_id,
|
||||
name = avatar.name,
|
||||
gender = avatar.gender.ToString(),
|
||||
date = avatar.date,
|
||||
skin_tone = avatar.skin_tone,
|
||||
head = avatar.head,
|
||||
body = avatar.body,
|
||||
description = avatar.description,
|
||||
budget = avatar.budget,
|
||||
moderation_level = avatar.moderation_level,
|
||||
body_swimwear = avatar.body_swimwear,
|
||||
body_sleepwear = avatar.body_sleepwear
|
||||
}).First();
|
||||
//for now, everything else assumes default values.
|
||||
}
|
||||
|
||||
|
||||
public List<DbAvatar> GetByUserId(uint user_id)
|
||||
{
|
||||
return Context.Connection.Query<DbAvatar>(
|
||||
"SELECT * FROM fso_avatars WHERE user_id = @user_id",
|
||||
new { user_id = user_id }
|
||||
).ToList();
|
||||
}
|
||||
|
||||
public List<DbAvatar> GetMultiple(uint[] id)
|
||||
{
|
||||
String inClause = "IN (";
|
||||
for (int i = 0; i < id.Length; i++)
|
||||
{
|
||||
inClause = inClause + "'" + id.ElementAt(i) + "'" + ",";
|
||||
}
|
||||
inClause = inClause.Substring(0, inClause.Length - 1);
|
||||
inClause = inClause + ")";
|
||||
|
||||
return Context.Connection.Query<DbAvatar>(
|
||||
"Select * from fso_avatars Where avatar_id "+ inClause
|
||||
).ToList();
|
||||
}
|
||||
|
||||
public List<DbAvatar> SearchExact(int shard_id, string name, int limit)
|
||||
{
|
||||
return Context.Connection.Query<DbAvatar>(
|
||||
"SELECT avatar_id, name FROM fso_avatars WHERE shard_id = @shard_id AND name = @name LIMIT @limit",
|
||||
new { name = name, limit = limit, shard_id = shard_id }
|
||||
).ToList();
|
||||
}
|
||||
|
||||
public List<DbAvatar> SearchWildcard(int shard_id, string name, int limit)
|
||||
{
|
||||
name = name
|
||||
.Replace("!", "!!")
|
||||
.Replace("%", "!%")
|
||||
.Replace("_", "!_")
|
||||
.Replace("[", "!["); //must sanitize format...
|
||||
return Context.Connection.Query<DbAvatar>(
|
||||
"SELECT avatar_id, name FROM fso_avatars WHERE shard_id = @shard_id AND name LIKE @name LIMIT @limit",
|
||||
new { name = "%" + name + "%", limit = limit, shard_id = shard_id }
|
||||
).ToList();
|
||||
}
|
||||
|
||||
public void UpdateDescription(uint id, string description)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_avatars SET description = @desc WHERE avatar_id = @id", new { id = id, desc = description });
|
||||
}
|
||||
|
||||
public void UpdatePrivacyMode(uint id, byte mode)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_avatars SET privacy_mode = @privacy_mode WHERE avatar_id = @id", new { id = id, privacy_mode = mode });
|
||||
}
|
||||
|
||||
public void UpdateMoveDate(uint id, uint date)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_avatars SET move_date = @date WHERE avatar_id = @id", new { id = id, date = date });
|
||||
}
|
||||
|
||||
public void UpdateMayorNhood(uint id, uint? nhood)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_avatars SET mayor_nhood = @nhood WHERE avatar_id = @id", new { id = id, nhood = nhood });
|
||||
}
|
||||
|
||||
|
||||
public void UpdateAvatarLotSave(uint id, DbAvatar avatar)
|
||||
{
|
||||
avatar.avatar_id = id;
|
||||
Context.Connection.Query("UPDATE fso_avatars SET "
|
||||
+ "motive_data = @motive_data, "
|
||||
+ "skilllock = @skilllock, "
|
||||
+ "lock_mechanical = @lock_mechanical, "
|
||||
+ "lock_cooking = @lock_cooking, "
|
||||
+ "lock_charisma = @lock_charisma, "
|
||||
+ "lock_logic = @lock_logic, "
|
||||
+ "lock_body = @lock_body, "
|
||||
+ "lock_creativity = @lock_creativity, "
|
||||
+ "skill_mechanical = @skill_mechanical, "
|
||||
+ "skill_cooking = @skill_cooking, "
|
||||
+ "skill_charisma = @skill_charisma, "
|
||||
+ "skill_logic = @skill_logic, "
|
||||
+ "skill_body = @skill_body, "
|
||||
+ "skill_creativity = @skill_creativity, "
|
||||
+ "body = @body, "
|
||||
+ "body_swimwear = @body_swimwear, "
|
||||
+ "body_sleepwear = @body_sleepwear, "
|
||||
+ "body_current = @body_current, "
|
||||
+ "current_job = @current_job, "
|
||||
+ "is_ghost = @is_ghost, "
|
||||
+ "ticker_death = @ticker_death, "
|
||||
+ "ticker_gardener = @ticker_gardener, "
|
||||
+ "ticker_maid = @ticker_maid, "
|
||||
+ "ticker_repairman = @ticker_repairman WHERE avatar_id = @avatar_id", avatar);
|
||||
}
|
||||
|
||||
private static string[] LockNames = new string[]
|
||||
{
|
||||
"lock_mechanical",
|
||||
"lock_cooking",
|
||||
"lock_charisma",
|
||||
"lock_logic",
|
||||
"lock_body",
|
||||
"lock_creativity"
|
||||
};
|
||||
|
||||
public int GetOtherLocks(uint avatar_id, string except)
|
||||
{
|
||||
string columns = "(";
|
||||
foreach (var l in LockNames)
|
||||
{
|
||||
if (l == except) continue;
|
||||
columns += l;
|
||||
columns += " + ";
|
||||
}
|
||||
columns += "0) AS Sum";
|
||||
|
||||
return Context.Connection.Query<int>("SELECT "+columns+" FROM fso_avatars WHERE avatar_id = @id", new { id = avatar_id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
//budget and transactions
|
||||
public int GetBudget(uint avatar_id)
|
||||
{
|
||||
return Context.Connection.Query<int>("SELECT budget FROM fso_avatars WHERE avatar_id = @id", new { id = avatar_id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public DbTransactionResult Transaction(uint source_id, uint dest_id, int amount, short reason)
|
||||
{
|
||||
return Transaction(source_id, dest_id, amount, reason, null);
|
||||
}
|
||||
|
||||
public DbTransactionResult Transaction(uint source_id, uint dest_id, int amount, short reason, Func<bool> transactionInject)
|
||||
{
|
||||
var t = Context.Connection.BeginTransaction();
|
||||
var srcObj = (source_id >= 16777216);
|
||||
var dstObj = (dest_id >= 16777216);
|
||||
var success = true;
|
||||
try {
|
||||
int srcRes, dstRes;
|
||||
if (source_id != uint.MaxValue)
|
||||
{
|
||||
if (srcObj)
|
||||
{
|
||||
srcRes = Context.Connection.Execute("UPDATE fso_objects SET budget = budget - @amount WHERE object_id = @source_id;",
|
||||
new { source_id = source_id, amount = amount });
|
||||
}
|
||||
else
|
||||
{
|
||||
srcRes = Context.Connection.Execute("UPDATE fso_avatars SET budget = budget - @amount WHERE avatar_id = @source_id;",
|
||||
new { source_id = source_id, amount = amount });
|
||||
}
|
||||
if (srcRes == 0) throw new Exception("Source avatar/object does not exist!");
|
||||
}
|
||||
|
||||
if (dest_id != uint.MaxValue)
|
||||
{
|
||||
if (dstObj)
|
||||
{
|
||||
dstRes = Context.Connection.Execute("UPDATE fso_objects SET budget = budget + @amount WHERE object_id = @dest_id;",
|
||||
new { dest_id = dest_id, amount = amount });
|
||||
}
|
||||
else
|
||||
{
|
||||
dstRes = Context.Connection.Execute("UPDATE fso_avatars SET budget = budget + @amount WHERE avatar_id = @dest_id;",
|
||||
new { dest_id = dest_id, amount = amount });
|
||||
}
|
||||
if (dstRes == 0) throw new Exception("Dest avatar/object does not exist!");
|
||||
}
|
||||
|
||||
if (transactionInject != null)
|
||||
{
|
||||
if (!transactionInject()) throw new Exception("Transaction Cancelled");
|
||||
}
|
||||
|
||||
t.Commit();
|
||||
} catch (Exception)
|
||||
{
|
||||
success = false;
|
||||
t.Rollback();
|
||||
}
|
||||
|
||||
if (success && ((reason > 7 && reason != 9) || (source_id != uint.MaxValue && dest_id != uint.MaxValue))) {
|
||||
var days = (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalDays;
|
||||
Context.Connection.Execute("INSERT INTO fso_transactions (from_id, to_id, transaction_type, day, value, count) "+
|
||||
"VALUES (@from_id, @to_id, @transaction_type, @day, @value, @count) " +
|
||||
"ON DUPLICATE KEY UPDATE value = value + @value, count = count+1", new
|
||||
{
|
||||
from_id = (amount>0)?source_id:dest_id,
|
||||
to_id = (amount>0)?dest_id:source_id,
|
||||
transaction_type = reason,
|
||||
day = (int)days,
|
||||
value = Math.Abs(amount),
|
||||
count = 1
|
||||
});
|
||||
}
|
||||
|
||||
var result = Context.Connection.Query<DbTransactionResult>("SELECT a1.budget AS source_budget, a2.budget AS dest_budget "
|
||||
+ "FROM"
|
||||
+ "(SELECT budget, count(budget) FROM " + (srcObj ? "fso_objects" : "fso_avatars") + " WHERE " + (srcObj ? "object_id" : "avatar_id") + " = @source_id) a1,"
|
||||
+ "(SELECT budget, count(budget) FROM " + (dstObj ? "fso_objects" : "fso_avatars") + " WHERE " + (dstObj ? "object_id" : "avatar_id") + " = @avatar_id) a2; ",
|
||||
new { avatar_id = dest_id, source_id = source_id }).FirstOrDefault();
|
||||
if (result != null)
|
||||
{
|
||||
result.amount = amount;
|
||||
result.success = success;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public DbTransactionResult TestTransaction(uint source_id, uint dest_id, int amount, short reason)
|
||||
{
|
||||
var success = true;
|
||||
var srcObj = (source_id >= 16777216);
|
||||
var dstObj = (dest_id >= 16777216);
|
||||
try
|
||||
{
|
||||
int? srcVal, dstVal;
|
||||
if (srcObj)
|
||||
{
|
||||
srcVal = Context.Connection.Query<int?>("SELECT budget FROM fso_objects WHERE object_id = @source_id;",
|
||||
new { source_id = source_id }).FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
srcVal = Context.Connection.Query<int?>("SELECT budget FROM fso_avatars WHERE avatar_id = @source_id;",
|
||||
new { source_id = source_id }).FirstOrDefault();
|
||||
}
|
||||
if (source_id != uint.MaxValue)
|
||||
{
|
||||
if (srcVal == null) throw new Exception("Source avatar/object does not exist!");
|
||||
if (srcVal.Value - amount < 0) throw new Exception("Source does not have enough money!");
|
||||
}
|
||||
if (dstObj)
|
||||
{
|
||||
dstVal = Context.Connection.Query<int?>("SELECT budget FROM fso_objects WHERE object_id = @dest_id;",
|
||||
new { dest_id = dest_id }).FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
dstVal = Context.Connection.Query<int?>("SELECT budget FROM fso_avatars WHERE avatar_id = @dest_id;",
|
||||
new { dest_id = dest_id }).FirstOrDefault();
|
||||
}
|
||||
if (dest_id != uint.MaxValue)
|
||||
{
|
||||
if (dstVal == null) throw new Exception("Dest avatar/object does not exist!");
|
||||
if (dstVal.Value + amount < 0) throw new Exception("Destination does not have enough money! (transaction accidentally debits)");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
var result = Context.Connection.Query<DbTransactionResult>("SELECT a1.budget AS source_budget, a2.budget AS dest_budget "
|
||||
+ "FROM"
|
||||
+ "(SELECT budget, count(budget) FROM "+(srcObj?"fso_objects":"fso_avatars")+" WHERE "+(srcObj?"object_id":"avatar_id")+" = @source_id) a1,"
|
||||
+ "(SELECT budget, count(budget) FROM " + (dstObj ? "fso_objects" : "fso_avatars") + " WHERE " + (dstObj ? "object_id" : "avatar_id") + " = @avatar_id) a2; ",
|
||||
new { avatar_id = dest_id, source_id = source_id }).FirstOrDefault();
|
||||
if (result != null)
|
||||
{
|
||||
result.amount = amount;
|
||||
result.success = success;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//JOB LEVELS
|
||||
|
||||
public DbJobLevel GetCurrentJobLevel(uint avatar_id)
|
||||
{
|
||||
return Context.Connection.Query<DbJobLevel>("SELECT * FROM fso_avatars a JOIN fso_joblevels b "
|
||||
+ "ON a.avatar_id = b.avatar_id AND a.current_job = b.job_type WHERE a.avatar_id = @id",
|
||||
new { id = avatar_id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public List<DbJobLevel> GetJobLevels(uint avatar_id)
|
||||
{
|
||||
return Context.Connection.Query<DbJobLevel>("SELECT * FROM fso_avatars a JOIN fso_joblevels b ON a.avatar_id = b.avatar_id WHERE a.avatar_id = @id", new { id = avatar_id }).ToList();
|
||||
}
|
||||
|
||||
public void UpdateAvatarJobLevel(DbJobLevel jobLevel)
|
||||
{
|
||||
Context.Connection.Query<DbJobLevel>("INSERT INTO fso_joblevels (avatar_id, job_type, job_experience, job_level, job_sickdays, job_statusflags) "
|
||||
+ "VALUES (@avatar_id, @job_type, @job_experience, @job_level, @job_sickdays, @job_statusflags) "
|
||||
+ "ON DUPLICATE KEY UPDATE job_experience=VALUES(`job_experience`), job_level=VALUES(`job_level`), "
|
||||
+" job_sickdays=VALUES(`job_sickdays`), job_statusflags=VALUES(`job_statusflags`); ", jobLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
public List<DbAvatarSummary> GetSummaryByUserId(uint user_id)
|
||||
{
|
||||
return Context.Connection.Query<DbAvatarSummary>(
|
||||
@"SELECT a.avatar_id,
|
||||
a.shard_id,
|
||||
a.user_id,
|
||||
a.name,
|
||||
a.gender,
|
||||
a.date,
|
||||
a.skin_tone,
|
||||
a.head,
|
||||
a.body,
|
||||
a.description,
|
||||
r.lot_id,
|
||||
l.name as lot_name,
|
||||
l.location as lot_location
|
||||
FROM fso_avatars a
|
||||
LEFT OUTER JOIN fso_roommates r on r.avatar_id = a.avatar_id
|
||||
LEFT OUTER JOIN fso_lots l on l.lot_id = r.lot_id AND r.is_pending = 0
|
||||
WHERE a.user_id = @user_id
|
||||
ORDER BY a.date ASC", new { user_id = user_id }).ToList();
|
||||
}
|
||||
}
|
||||
}
|
10
server/FSO.Server.Database/DA/Bans/DbBan.cs
Executable file
10
server/FSO.Server.Database/DA/Bans/DbBan.cs
Executable file
|
@ -0,0 +1,10 @@
|
|||
namespace FSO.Server.Database.DA.Bans
|
||||
{
|
||||
public class DbBan
|
||||
{
|
||||
public uint user_id { get; set; }
|
||||
public string ip_address { get; set; }
|
||||
public string ban_reason { get; set; }
|
||||
public int end_date { get; set; }
|
||||
}
|
||||
}
|
11
server/FSO.Server.Database/DA/Bans/IBans.cs
Executable file
11
server/FSO.Server.Database/DA/Bans/IBans.cs
Executable file
|
@ -0,0 +1,11 @@
|
|||
namespace FSO.Server.Database.DA.Bans
|
||||
{
|
||||
public interface IBans
|
||||
{
|
||||
DbBan GetByIP(string ip);
|
||||
void Add(string ip, uint userid, string reason, int enddate, string client_id);
|
||||
|
||||
DbBan GetByClientId(string client_id);
|
||||
void Remove(uint user_id);
|
||||
}
|
||||
}
|
51
server/FSO.Server.Database/DA/Bans/SqlBans.cs
Executable file
51
server/FSO.Server.Database/DA/Bans/SqlBans.cs
Executable file
|
@ -0,0 +1,51 @@
|
|||
using Dapper;
|
||||
using System.Linq;
|
||||
|
||||
namespace FSO.Server.Database.DA.Bans
|
||||
{
|
||||
public class SqlBans : AbstractSqlDA, IBans
|
||||
{
|
||||
public SqlBans(ISqlContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public DbBan GetByIP(string ip)
|
||||
{
|
||||
return Context.Connection.Query<DbBan>("SELECT * FROM fso_ip_ban WHERE ip_address = @ip", new { ip = ip }).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a ban by MAC Address.
|
||||
/// </summary>
|
||||
/// <param name="client_id"></param>
|
||||
/// <returns></returns>
|
||||
public DbBan GetByClientId(string client_id)
|
||||
{
|
||||
return Context.Connection.Query<DbBan>("SELECT * FROM fso_ip_ban WHERE client_id = @client_id", new { client_id = client_id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public void Add(string ip, uint userid, string reason, int enddate, string client_id)
|
||||
{
|
||||
Context.Connection.Execute(
|
||||
"REPLACE INTO fso_ip_ban (user_id, ip_address, banreason, end_date, client_id) " +
|
||||
"VALUES (@user_id, @ip_address, @banreason, @end_date, @client_id)",
|
||||
new
|
||||
{
|
||||
user_id = userid,
|
||||
ip_address = ip,
|
||||
banreason = reason,
|
||||
end_date = enddate
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove ban by user_id.
|
||||
/// </summary>
|
||||
/// <param name="ip"></param>
|
||||
public void Remove(uint user_id)
|
||||
{
|
||||
Context.Connection.Query("DELETE FROM fso_ip_ban WHERE user_id = @user_id", new { user_id = user_id });
|
||||
}
|
||||
}
|
||||
}
|
14
server/FSO.Server.Database/DA/Bonus/DbBonus.cs
Executable file
14
server/FSO.Server.Database/DA/Bonus/DbBonus.cs
Executable file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
namespace FSO.Server.Database.DA.Bonus
|
||||
{
|
||||
public class DbBonus
|
||||
{
|
||||
public int bonus_id { get; set; }
|
||||
public uint avatar_id { get; set; }
|
||||
public DateTime period { get; set; }
|
||||
public int? bonus_visitor { get; set; }
|
||||
public int? bonus_property { get; set; }
|
||||
public int? bonus_sim { get; set; }
|
||||
}
|
||||
}
|
14
server/FSO.Server.Database/DA/Bonus/DbBonusMetrics.cs
Executable file
14
server/FSO.Server.Database/DA/Bonus/DbBonusMetrics.cs
Executable file
|
@ -0,0 +1,14 @@
|
|||
using FSO.Common.Enum;
|
||||
|
||||
namespace FSO.Server.Database.DA.Bonus
|
||||
{
|
||||
public class DbBonusMetrics
|
||||
{
|
||||
public uint avatar_id { get; set; }
|
||||
public int lot_id { get; set; }
|
||||
public LotCategory category { get; set; }
|
||||
public int? visitor_minutes { get; set; }
|
||||
public byte? property_rank { get; set; }
|
||||
public byte? sim_rank { get; set; }
|
||||
}
|
||||
}
|
13
server/FSO.Server.Database/DA/Bonus/IBonus.cs
Executable file
13
server/FSO.Server.Database/DA/Bonus/IBonus.cs
Executable file
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Bonus
|
||||
{
|
||||
public interface IBonus
|
||||
{
|
||||
IEnumerable<DbBonus> GetByAvatarId(uint avatar_id);
|
||||
IEnumerable<DbBonusMetrics> GetMetrics(DateTime date, int shard_id);
|
||||
void Insert(IEnumerable<DbBonus> bonus);
|
||||
void Purge(DateTime date);
|
||||
}
|
||||
}
|
50
server/FSO.Server.Database/DA/Bonus/SqlBonus.cs
Executable file
50
server/FSO.Server.Database/DA/Bonus/SqlBonus.cs
Executable file
|
@ -0,0 +1,50 @@
|
|||
using Dapper;
|
||||
using FSO.Server.Database.DA.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Bonus
|
||||
{
|
||||
public class SqlBonus : AbstractSqlDA, IBonus
|
||||
{
|
||||
public SqlBonus(ISqlContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public IEnumerable<DbBonus> GetByAvatarId(uint avatar_id)
|
||||
{
|
||||
return Context.Connection.Query<DbBonus>("SELECT * FROM fso_bonus WHERE avatar_id = @avatar_id ORDER BY period DESC LIMIT 14", new { avatar_id = avatar_id });
|
||||
}
|
||||
|
||||
public IEnumerable<DbBonusMetrics> GetMetrics(DateTime date, int shard_id)
|
||||
{
|
||||
return Context.Connection.Query<DbBonusMetrics>(
|
||||
@"SELECT * FROM (
|
||||
SELECT a.avatar_id,
|
||||
r.lot_id,
|
||||
l.category,
|
||||
(SELECT lvt.minutes from fso_lot_visit_totals lvt where lvt.lot_id = r.lot_id AND lvt.date = CAST(@p_date as DATE)) as visitor_minutes,
|
||||
(SELECT rank from fso_lot_top_100 lt100 WHERE lt100.lot_id = r.lot_id) as property_rank,
|
||||
NULL as sim_rank
|
||||
FROM fso_avatars a
|
||||
LEFT JOIN fso_roommates r ON r.avatar_id = a.avatar_id
|
||||
LEFT JOIN fso_lots l ON r.lot_id = l.lot_id
|
||||
WHERE a.shard_id = @p_shard_id
|
||||
) as bonusPayments
|
||||
WHERE visitor_minutes IS NOT NULL
|
||||
OR property_rank IS NOT NULL
|
||||
OR sim_rank IS NOT NULL"
|
||||
, new { p_date = date, p_shard_id = shard_id }, buffered: false);
|
||||
}
|
||||
|
||||
public void Insert(IEnumerable<DbBonus> bonus)
|
||||
{
|
||||
Context.Connection.ExecuteBufferedInsert("INSERT INTO fso_bonus (avatar_id, period, bonus_visitor, bonus_property, bonus_sim) VALUES (@avatar_id, @period, @bonus_visitor, @bonus_property, @bonus_sim) ON DUPLICATE KEY UPDATE fso_bonus.avatar_id = fso_bonus.avatar_id", bonus, 100);
|
||||
}
|
||||
|
||||
public void Purge(DateTime date)
|
||||
{
|
||||
Context.Connection.Execute("DELETE FROM fso_bonus WHERE period < @date", new { date = date });
|
||||
}
|
||||
}
|
||||
}
|
9
server/FSO.Server.Database/DA/Bookmarks/DbBookmark.cs
Executable file
9
server/FSO.Server.Database/DA/Bookmarks/DbBookmark.cs
Executable file
|
@ -0,0 +1,9 @@
|
|||
namespace FSO.Server.Database.DA.Bookmarks
|
||||
{
|
||||
public class DbBookmark
|
||||
{
|
||||
public uint avatar_id { get; set; }
|
||||
public byte type { get; set; }
|
||||
public uint target_id { get; set; }
|
||||
}
|
||||
}
|
12
server/FSO.Server.Database/DA/Bookmarks/IBookmarks.cs
Executable file
12
server/FSO.Server.Database/DA/Bookmarks/IBookmarks.cs
Executable file
|
@ -0,0 +1,12 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Bookmarks
|
||||
{
|
||||
public interface IBookmarks
|
||||
{
|
||||
List<DbBookmark> GetByAvatarId(uint avatar_id);
|
||||
List<uint> GetAvatarIgnore(uint avatar_id);
|
||||
void Create(DbBookmark bookmark);
|
||||
bool Delete(DbBookmark bookmark);
|
||||
}
|
||||
}
|
35
server/FSO.Server.Database/DA/Bookmarks/SqlBookmarks.cs
Executable file
35
server/FSO.Server.Database/DA/Bookmarks/SqlBookmarks.cs
Executable file
|
@ -0,0 +1,35 @@
|
|||
using Dapper;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace FSO.Server.Database.DA.Bookmarks
|
||||
{
|
||||
public class SqlBookmarks : AbstractSqlDA, IBookmarks
|
||||
{
|
||||
public SqlBookmarks(ISqlContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public void Create(DbBookmark bookmark)
|
||||
{
|
||||
Context.Connection.Execute("INSERT INTO fso_bookmarks (avatar_id, type, target_id) " +
|
||||
" VALUES (@avatar_id, @type, @target_id)"
|
||||
, bookmark);
|
||||
}
|
||||
|
||||
public bool Delete(DbBookmark bookmark)
|
||||
{
|
||||
return Context.Connection.Execute("DELETE FROM fso_bookmarks WHERE avatar_id = @avatar_id AND type = @type AND target_id = @target_id", bookmark) > 0;
|
||||
}
|
||||
|
||||
public List<DbBookmark> GetByAvatarId(uint avatar_id)
|
||||
{
|
||||
return Context.Connection.Query<DbBookmark>("SELECT * FROM fso_bookmarks WHERE avatar_id = @avatar_id", new { avatar_id = avatar_id }).ToList();
|
||||
}
|
||||
|
||||
public List<uint> GetAvatarIgnore(uint avatar_id)
|
||||
{
|
||||
return Context.Connection.Query<uint>("SELECT target_id FROM fso_bookmarks WHERE avatar_id = @avatar_id AND type = 5", new { avatar_id = avatar_id }).ToList();
|
||||
}
|
||||
}
|
||||
}
|
29
server/FSO.Server.Database/DA/Bulletin/DbBulletinPost.cs
Executable file
29
server/FSO.Server.Database/DA/Bulletin/DbBulletinPost.cs
Executable file
|
@ -0,0 +1,29 @@
|
|||
namespace FSO.Server.Database.DA.Bulletin
|
||||
{
|
||||
public class DbBulletinPost
|
||||
{
|
||||
public uint bulletin_id { get; set; }
|
||||
public int neighborhood_id { get; set; }
|
||||
public uint? avatar_id { get; set; }
|
||||
public string title { get; set; }
|
||||
public string body { get; set; }
|
||||
public uint date { get; set; }
|
||||
public uint flags { get; set; }
|
||||
public int? lot_id { get; set; }
|
||||
public DbBulletinType type { get; set; }
|
||||
public byte deleted { get; set; }
|
||||
|
||||
public string string_type { get
|
||||
{
|
||||
return type.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum DbBulletinType
|
||||
{
|
||||
mayor,
|
||||
system,
|
||||
community
|
||||
}
|
||||
}
|
17
server/FSO.Server.Database/DA/Bulletin/IBulletinPosts.cs
Executable file
17
server/FSO.Server.Database/DA/Bulletin/IBulletinPosts.cs
Executable file
|
@ -0,0 +1,17 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Bulletin
|
||||
{
|
||||
public interface IBulletinPosts
|
||||
{
|
||||
DbBulletinPost Get(uint bulletin_id);
|
||||
int CountPosts(uint neighborhood_id, uint timeAfter);
|
||||
uint LastPostID(uint neighborhood_id);
|
||||
DbBulletinPost LastUserPost(uint user_id, uint neighborhood_id);
|
||||
List<DbBulletinPost> GetByNhoodId(uint neighborhood_id, uint timeAfter);
|
||||
uint Create(DbBulletinPost bulletin);
|
||||
bool Delete(uint bulletin_id);
|
||||
bool SoftDelete(uint bulletin_id);
|
||||
bool SetTypeFlag(uint bulletin_id, DbBulletinType type, int flag);
|
||||
}
|
||||
}
|
70
server/FSO.Server.Database/DA/Bulletin/SqlBulletinPosts.cs
Executable file
70
server/FSO.Server.Database/DA/Bulletin/SqlBulletinPosts.cs
Executable file
|
@ -0,0 +1,70 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Dapper;
|
||||
|
||||
namespace FSO.Server.Database.DA.Bulletin
|
||||
{
|
||||
public class SqlBulletinPosts : AbstractSqlDA, IBulletinPosts
|
||||
{
|
||||
public SqlBulletinPosts(ISqlContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public uint Create(DbBulletinPost bulletin)
|
||||
{
|
||||
return Context.Connection.Query<uint>("INSERT INTO fso_bulletin_posts (neighborhood_id, avatar_id, title, body, date, flags, lot_id, type) " +
|
||||
" VALUES (@neighborhood_id, @avatar_id, @title, @body, @date, @flags, @lot_id, @string_type); SELECT LAST_INSERT_ID();"
|
||||
, bulletin).First();
|
||||
}
|
||||
|
||||
public bool Delete(uint bulletin_id)
|
||||
{
|
||||
return Context.Connection.Execute("DELETE FROM fso_bulletin_posts WHERE bulletin_id = @bulletin_id", new { bulletin_id }) > 0;
|
||||
}
|
||||
|
||||
public bool SoftDelete(uint bulletin_id)
|
||||
{
|
||||
return Context.Connection.Execute("UPDATE fso_bulletin_posts SET deleted = 1 WHERE bulletin_id = @bulletin_id",
|
||||
new { bulletin_id }) > 0;
|
||||
}
|
||||
|
||||
public bool SetTypeFlag(uint bulletin_id, DbBulletinType type, int flags)
|
||||
{
|
||||
return Context.Connection.Execute("UPDATE fso_bulletin_posts SET flags = @flags, type = @type WHERE bulletin_id = @bulletin_id",
|
||||
new { bulletin_id, type = type.ToString(), flags }) > 0;
|
||||
}
|
||||
|
||||
public List<DbBulletinPost> GetByNhoodId(uint neighborhood_id, uint timeAfter)
|
||||
{
|
||||
return Context.Connection.Query<DbBulletinPost>("SELECT * FROM fso_bulletin_posts WHERE deleted = 0 AND neighborhood_id = @neighborhood_id AND date > @timeAfter",
|
||||
new { neighborhood_id, timeAfter }).ToList();
|
||||
}
|
||||
|
||||
public int CountPosts(uint neighborhood_id, uint timeAfter)
|
||||
{
|
||||
return Context.Connection.Query<int>("SELECT count(*) FROM fso_bulletin_posts WHERE neighborhood_id = @neighborhood_id AND deleted = 0 AND date > @timeAfter",
|
||||
new { neighborhood_id, timeAfter }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public uint LastPostID(uint neighborhood_id)
|
||||
{
|
||||
return Context.Connection.Query<uint>("SELECT bulletin_id FROM fso_bulletin_posts WHERE deleted = 0 AND neighborhood_id = @neighborhood_id ORDER BY bulletin_id DESC LIMIT 1",
|
||||
new { neighborhood_id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public DbBulletinPost Get(uint bulletin_id)
|
||||
{
|
||||
return Context.Connection.Query<DbBulletinPost>("SELECT * FROM fso_bulletin_posts WHERE bulletin_id = @bulletin_id",
|
||||
new { bulletin_id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public DbBulletinPost LastUserPost(uint user_id, uint neighborhood_id)
|
||||
{
|
||||
return Context.Connection.Query<DbBulletinPost>("SELECT b.* FROM fso_bulletin_posts b " +
|
||||
"JOIN fso_avatars a ON b.avatar_id = a.avatar_id WHERE a.user_id = @user_id AND b.neighborhood_id = @neighborhood_id " +
|
||||
"ORDER BY b.date DESC " +
|
||||
"LIMIT 1",
|
||||
new { user_id, neighborhood_id }).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
10
server/FSO.Server.Database/DA/DbChanges/DbChange.cs
Executable file
10
server/FSO.Server.Database/DA/DbChanges/DbChange.cs
Executable file
|
@ -0,0 +1,10 @@
|
|||
namespace FSO.Server.Database.DA.DbChanges
|
||||
{
|
||||
public class DbChange
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string filename { get; set; }
|
||||
public uint date { get; set; }
|
||||
public string hash { get; set; }
|
||||
}
|
||||
}
|
41
server/FSO.Server.Database/DA/DbEvents/DbEvent.cs
Executable file
41
server/FSO.Server.Database/DA/DbEvents/DbEvent.cs
Executable file
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
|
||||
namespace FSO.Server.Database.DA.DbEvents
|
||||
{
|
||||
public class DbEvent
|
||||
{
|
||||
public int event_id { get; set; }
|
||||
public string title { get; set; }
|
||||
public string description { get; set; }
|
||||
public DateTime start_day { get; set; }
|
||||
public DateTime end_day { get; set; }
|
||||
public DbEventType type { get; set; }
|
||||
public int value { get; set; }
|
||||
public int value2 { get; set; }
|
||||
public string mail_subject { get; set; }
|
||||
public string mail_message { get; set; }
|
||||
public int? mail_sender { get; set; }
|
||||
public string mail_sender_name { get; set; }
|
||||
|
||||
public string type_str {
|
||||
get {
|
||||
return type.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DbEventParticipation
|
||||
{
|
||||
public int event_id { get; set; }
|
||||
public uint user_id { get; set; }
|
||||
}
|
||||
|
||||
public enum DbEventType
|
||||
{
|
||||
mail_only,
|
||||
free_object,
|
||||
free_money,
|
||||
free_green,
|
||||
obj_tuning
|
||||
}
|
||||
}
|
8
server/FSO.Server.Database/DA/DbEvents/DbGenericAvatarParticipation.cs
Executable file
8
server/FSO.Server.Database/DA/DbEvents/DbGenericAvatarParticipation.cs
Executable file
|
@ -0,0 +1,8 @@
|
|||
namespace FSO.Server.Database.DA.DbEvents
|
||||
{
|
||||
public class DbGenericAvatarParticipation
|
||||
{
|
||||
public string participation_name { get; set; }
|
||||
public uint participation_avatar { get; set; }
|
||||
}
|
||||
}
|
24
server/FSO.Server.Database/DA/DbEvents/IEvents.cs
Executable file
24
server/FSO.Server.Database/DA/DbEvents/IEvents.cs
Executable file
|
@ -0,0 +1,24 @@
|
|||
using FSO.Server.Database.DA.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.DbEvents
|
||||
{
|
||||
public interface IEvents
|
||||
{
|
||||
PagedList<DbEvent> All(int offset = 0, int limit = 20, string orderBy = "start_day");
|
||||
List<DbEvent> GetActive(DateTime time);
|
||||
int Add(DbEvent evt);
|
||||
bool Delete(int event_id);
|
||||
|
||||
bool TryParticipate(DbEventParticipation p);
|
||||
bool Participated(DbEventParticipation p);
|
||||
List<uint> GetParticipatingUsers(int event_id);
|
||||
|
||||
bool GenericAvaTryParticipate(DbGenericAvatarParticipation p);
|
||||
bool GenericAvaParticipated(DbGenericAvatarParticipation p);
|
||||
List<uint> GetGenericParticipatingAvatars(string genericName);
|
||||
|
||||
List<DbEvent> GetLatestNameDesc(int limit);
|
||||
}
|
||||
}
|
95
server/FSO.Server.Database/DA/DbEvents/SqlEvents.cs
Executable file
95
server/FSO.Server.Database/DA/DbEvents/SqlEvents.cs
Executable file
|
@ -0,0 +1,95 @@
|
|||
using System;
|
||||
using Dapper;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FSO.Server.Database.DA.Utils;
|
||||
|
||||
namespace FSO.Server.Database.DA.DbEvents
|
||||
{
|
||||
public class SqlEvents : AbstractSqlDA, IEvents
|
||||
{
|
||||
public SqlEvents(ISqlContext context) : base(context){
|
||||
}
|
||||
|
||||
public PagedList<DbEvent> All(int offset = 1, int limit = 20, string orderBy = "start_day")
|
||||
{
|
||||
var connection = Context.Connection;
|
||||
var total = connection.Query<int>("SELECT COUNT(*) FROM fso_events").FirstOrDefault();
|
||||
var results = connection.Query<DbEvent>("SELECT * FROM fso_events ORDER BY @order DESC LIMIT @offset, @limit", new { order = orderBy, offset = offset, limit = limit });
|
||||
return new PagedList<DbEvent>(results, offset, total);
|
||||
}
|
||||
|
||||
public int Add(DbEvent evt)
|
||||
{
|
||||
var result = Context.Connection.Query<int>("INSERT INTO fso_events (title, description, start_day, " +
|
||||
"end_day, type, value, value2, mail_subject, mail_message, mail_sender, mail_sender_name) " +
|
||||
" VALUES (@title, @description, @start_day, @end_day, @type_str, @value, @value2, " +
|
||||
" @mail_subject, @mail_message, @mail_sender, @mail_sender_name); SELECT LAST_INSERT_ID();", evt).First();
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool Delete(int event_id)
|
||||
{
|
||||
return Context.Connection.Execute("DELETE FROM fso_events WHERE event_id = @event_id", new { event_id = event_id }) > 0;
|
||||
}
|
||||
|
||||
public List<DbEvent> GetActive(DateTime time)
|
||||
{
|
||||
return Context.Connection.Query<DbEvent>("SELECT * FROM fso_events WHERE start_day <= @time AND end_day >= @time", new { time = time }).ToList();
|
||||
}
|
||||
|
||||
public List<DbEvent> GetLatestNameDesc(int limit)
|
||||
{
|
||||
return Context.Connection.Query<DbEvent>("SELECT * FROM fso_events WHERE title IS NOT NULL AND description IS NOT NULL ORDER BY start_day DESC LIMIT "+limit).ToList();
|
||||
}
|
||||
|
||||
public List<uint> GetParticipatingUsers(int event_id)
|
||||
{
|
||||
return Context.Connection.Query<uint>("SELECT user_id FROM fso_event_participation WHERE event_id = @event_id", new { event_id = event_id }).ToList();
|
||||
}
|
||||
|
||||
public bool Participated(DbEventParticipation p)
|
||||
{
|
||||
return Context.Connection.Query<int>("SELECT count(*) FROM fso_event_participation WHERE event_id = @event_id AND user_id = @user_id", p).First() > 0;
|
||||
}
|
||||
|
||||
public bool TryParticipate(DbEventParticipation p)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Context.Connection.Execute("INSERT INTO fso_event_participation (event_id, user_id) VALUES (@event_id, @user_id)", p) > 0);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//already exists, or foreign key fails
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool GenericAvaTryParticipate(DbGenericAvatarParticipation p)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Context.Connection.Execute("INSERT INTO fso_generic_avatar_participation (participation_name, participation_avatar) " +
|
||||
"VALUES (@participation_name, @participation_avatar)", p) > 0);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//already exists, or foreign key fails
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool GenericAvaParticipated(DbGenericAvatarParticipation p)
|
||||
{
|
||||
return Context.Connection.Query<int>("SELECT count(*) FROM fso_generic_avatar_participation " +
|
||||
"WHERE participation_name = @participation_name AND participation_avatar = @participation_avatar", p).First() > 0;
|
||||
}
|
||||
|
||||
public List<uint> GetGenericParticipatingAvatars(string genericName)
|
||||
{
|
||||
return Context.Connection.Query<uint>("SELECT participation_avatar FROM fso_generic_avatar_participation " +
|
||||
"WHERE participation_name = @participation_name", new { participation_name = genericName }).ToList();
|
||||
}
|
||||
}
|
||||
}
|
10
server/FSO.Server.Database/DA/DynPayouts/DbDynPayout.cs
Executable file
10
server/FSO.Server.Database/DA/DynPayouts/DbDynPayout.cs
Executable file
|
@ -0,0 +1,10 @@
|
|||
namespace FSO.Server.Database.DA.DynPayouts
|
||||
{
|
||||
public class DbDynPayout
|
||||
{
|
||||
public int day { get; set; }
|
||||
public int skilltype { get; set; }
|
||||
public float multiplier { get; set; }
|
||||
public int flags { get; set; }
|
||||
}
|
||||
}
|
9
server/FSO.Server.Database/DA/DynPayouts/DbTransSummary.cs
Executable file
9
server/FSO.Server.Database/DA/DynPayouts/DbTransSummary.cs
Executable file
|
@ -0,0 +1,9 @@
|
|||
namespace FSO.Server.Database.DA.DynPayouts
|
||||
{
|
||||
public class DbTransSummary
|
||||
{
|
||||
public int transaction_type { get; set; }
|
||||
public int value { get; set; }
|
||||
public int sum { get; set; }
|
||||
}
|
||||
}
|
15
server/FSO.Server.Database/DA/DynPayouts/IDynPayouts.cs
Executable file
15
server/FSO.Server.Database/DA/DynPayouts/IDynPayouts.cs
Executable file
|
@ -0,0 +1,15 @@
|
|||
using FSO.Server.Database.DA.Tuning;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.DynPayouts
|
||||
{
|
||||
public interface IDynPayouts
|
||||
{
|
||||
List<DbTransSummary> GetSummary(int limitDay);
|
||||
bool InsertDynRecord(List<DbDynPayout> dynPayout);
|
||||
bool ReplaceDynTuning(List<DbTuning> dynTuning);
|
||||
|
||||
List<DbDynPayout> GetPayoutHistory(int limitDay);
|
||||
bool Purge(int limitDay);
|
||||
}
|
||||
}
|
59
server/FSO.Server.Database/DA/DynPayouts/SqlDynPayouts.cs
Executable file
59
server/FSO.Server.Database/DA/DynPayouts/SqlDynPayouts.cs
Executable file
|
@ -0,0 +1,59 @@
|
|||
using Dapper;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FSO.Server.Database.DA.Tuning;
|
||||
using FSO.Server.Database.DA.Utils;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
namespace FSO.Server.Database.DA.DynPayouts
|
||||
{
|
||||
public class SqlDynPayouts : AbstractSqlDA, IDynPayouts
|
||||
{
|
||||
public SqlDynPayouts(ISqlContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public List<DbDynPayout> GetPayoutHistory(int limitDay)
|
||||
{
|
||||
return Context.Connection.Query<DbDynPayout>("SELECT * FROM fso_dyn_payouts ORDER BY day DESC LIMIT 56", new { limitDay = limitDay }).ToList();
|
||||
}
|
||||
|
||||
public List<DbTransSummary> GetSummary(int limitDay)
|
||||
{
|
||||
return Context.Connection.Query<DbTransSummary>("SELECT transaction_type, sum(value) AS value, sum(count) AS sum FROM fso.fso_transactions "
|
||||
+"WHERE transaction_type > 40 AND transaction_type < 51 AND day >= @limitDay GROUP BY transaction_type", new { limitDay = limitDay }).ToList();
|
||||
}
|
||||
|
||||
public bool InsertDynRecord(List<DbDynPayout> dynPayout)
|
||||
{
|
||||
try
|
||||
{
|
||||
Context.Connection.ExecuteBufferedInsert("INSERT INTO fso_dyn_payouts (day, skilltype, multiplier, flags) VALUES (@day, @skilltype, @multiplier, @flags) ON DUPLICATE KEY UPDATE multiplier = @multiplier", dynPayout, 100);
|
||||
}
|
||||
catch (SqlException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Purge(int limitDay)
|
||||
{
|
||||
Context.Connection.Query("DELETE FROM fso_dyn_payouts WHERE day < @day", new { day = limitDay });
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ReplaceDynTuning(List<DbTuning> dynTuning)
|
||||
{
|
||||
try
|
||||
{
|
||||
var deleted = Context.Connection.Execute("DELETE FROM fso_tuning WHERE owner_type = 'DYNAMIC' AND owner_id = 1");
|
||||
Context.Connection.ExecuteBufferedInsert("INSERT INTO fso_tuning (tuning_type, tuning_table, tuning_index, value, owner_type, owner_id) VALUES (@tuning_type, @tuning_table, @tuning_index, @value, @owner_type, @owner_id)", dynTuning, 100);
|
||||
} catch (SqlException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
19
server/FSO.Server.Database/DA/Elections/DbElectionCandidate.cs
Executable file
19
server/FSO.Server.Database/DA/Elections/DbElectionCandidate.cs
Executable file
|
@ -0,0 +1,19 @@
|
|||
namespace FSO.Server.Database.DA.Elections
|
||||
{
|
||||
public class DbElectionCandidate
|
||||
{
|
||||
public uint election_cycle_id { get; set; }
|
||||
public uint candidate_avatar_id { get; set; }
|
||||
public string comment { get; set; }
|
||||
public DbCandidateState state { get; set; }
|
||||
}
|
||||
|
||||
public enum DbCandidateState
|
||||
{
|
||||
informed,
|
||||
running,
|
||||
disqualified,
|
||||
lost,
|
||||
won
|
||||
}
|
||||
}
|
30
server/FSO.Server.Database/DA/Elections/DbElectionCycle.cs
Executable file
30
server/FSO.Server.Database/DA/Elections/DbElectionCycle.cs
Executable file
|
@ -0,0 +1,30 @@
|
|||
namespace FSO.Server.Database.DA.Elections
|
||||
{
|
||||
public class DbElectionCycle
|
||||
{
|
||||
public uint cycle_id { get; set; }
|
||||
public uint start_date { get; set; }
|
||||
public uint end_date { get; set; }
|
||||
public DbElectionCycleState current_state { get; set; }
|
||||
public DbElectionCycleType election_type { get; set; }
|
||||
|
||||
//for free vote
|
||||
public string name { get; set; }
|
||||
public int nhood_id { get; set; }
|
||||
}
|
||||
|
||||
public enum DbElectionCycleState : byte
|
||||
{
|
||||
shutdown,
|
||||
nomination,
|
||||
election,
|
||||
ended,
|
||||
failsafe
|
||||
}
|
||||
|
||||
public enum DbElectionCycleType : byte
|
||||
{
|
||||
election,
|
||||
shutdown
|
||||
}
|
||||
}
|
9
server/FSO.Server.Database/DA/Elections/DbElectionCycleMail.cs
Executable file
9
server/FSO.Server.Database/DA/Elections/DbElectionCycleMail.cs
Executable file
|
@ -0,0 +1,9 @@
|
|||
namespace FSO.Server.Database.DA.Elections
|
||||
{
|
||||
public class DbElectionCycleMail
|
||||
{
|
||||
public uint avatar_id { get; set; }
|
||||
public uint cycle_id { get; set; }
|
||||
public DbElectionCycleState cycle_state { get; set; }
|
||||
}
|
||||
}
|
11
server/FSO.Server.Database/DA/Elections/DbElectionFreeVote.cs
Executable file
11
server/FSO.Server.Database/DA/Elections/DbElectionFreeVote.cs
Executable file
|
@ -0,0 +1,11 @@
|
|||
namespace FSO.Server.Database.DA.Elections
|
||||
{
|
||||
public class DbElectionFreeVote
|
||||
{
|
||||
public uint avatar_id { get; set; }
|
||||
public int neighborhood_id { get; set; }
|
||||
public uint cycle_id { get; set; }
|
||||
public uint date { get; set; }
|
||||
public uint expire_date { get; set; }
|
||||
}
|
||||
}
|
18
server/FSO.Server.Database/DA/Elections/DbElectionVote.cs
Executable file
18
server/FSO.Server.Database/DA/Elections/DbElectionVote.cs
Executable file
|
@ -0,0 +1,18 @@
|
|||
namespace FSO.Server.Database.DA.Elections
|
||||
{
|
||||
public class DbElectionVote
|
||||
{
|
||||
public uint election_cycle_id { get; set; }
|
||||
public uint from_avatar_id { get; set; }
|
||||
public DbElectionVoteType type { get; set; }
|
||||
public uint target_avatar_id { get; set; }
|
||||
public uint date { get; set; }
|
||||
public int value { get; set; }
|
||||
}
|
||||
|
||||
public enum DbElectionVoteType
|
||||
{
|
||||
vote,
|
||||
nomination
|
||||
}
|
||||
}
|
18
server/FSO.Server.Database/DA/Elections/DbMayorRating.cs
Executable file
18
server/FSO.Server.Database/DA/Elections/DbMayorRating.cs
Executable file
|
@ -0,0 +1,18 @@
|
|||
namespace FSO.Server.Database.DA.Elections
|
||||
{
|
||||
public class DbMayorRating
|
||||
{
|
||||
public uint rating_id { get; set; }
|
||||
public uint from_user_id { get; set; }
|
||||
public uint to_user_id { get; set; }
|
||||
|
||||
public uint rating { get; set; }
|
||||
public string comment { get; set; }
|
||||
public uint date { get; set; }
|
||||
|
||||
public uint from_avatar_id { get; set; }
|
||||
public uint to_avatar_id { get; set; }
|
||||
public byte anonymous { get; set; }
|
||||
public uint neighborhood { get; set; }
|
||||
}
|
||||
}
|
42
server/FSO.Server.Database/DA/Elections/IElections.cs
Executable file
42
server/FSO.Server.Database/DA/Elections/IElections.cs
Executable file
|
@ -0,0 +1,42 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Elections
|
||||
{
|
||||
public interface IElections
|
||||
{
|
||||
DbElectionCycle GetCycle(uint cycle_id);
|
||||
DbElectionCandidate GetCandidate(uint avatar_id, uint cycle_id, DbCandidateState state);
|
||||
List<DbElectionCycle> GetActiveCycles(int shard_id);
|
||||
List<DbElectionCandidate> GetCandidates(uint cycle_id, DbCandidateState state);
|
||||
List<DbElectionCandidate> GetCandidates(uint cycle_id);
|
||||
List<DbElectionVote> GetCycleVotes(uint cycle_id, DbElectionVoteType type);
|
||||
List<DbElectionVote> GetCycleVotesForAvatar(uint avatar_id, uint cycle_id, DbElectionVoteType type);
|
||||
DbElectionVote GetMyVote(uint avatar_id, uint cycle_id, DbElectionVoteType type);
|
||||
DbMayorRating GetSpecificRating(uint from_user_id, uint to_avatar_id);
|
||||
DbMayorRating GetRating(uint rating_id);
|
||||
List<uint> GetRatings(uint to_avatar_id);
|
||||
float? GetAvgRating(uint to_avatar_id);
|
||||
bool CreateCandidate(DbElectionCandidate candidate);
|
||||
bool SetCandidateState(DbElectionCandidate candidate);
|
||||
bool DeleteCandidate(uint election_cycle_id, uint candidate_avatar_id);
|
||||
uint CreateCycle(DbElectionCycle cycle);
|
||||
bool CreateVote(DbElectionVote vote);
|
||||
void UpdateCycleState(uint cycle_id, DbElectionCycleState state);
|
||||
uint SetRating(DbMayorRating rating);
|
||||
bool DeleteRating(uint id);
|
||||
|
||||
bool EmailRegistered(DbElectionCycleMail p);
|
||||
bool TryRegisterMail(DbElectionCycleMail p);
|
||||
|
||||
bool EnrollFreeVote(DbElectionFreeVote entry);
|
||||
DbElectionFreeVote GetFreeVote(uint avatar_id);
|
||||
|
||||
DbElectionWin FindLastWin(uint avatar_id);
|
||||
}
|
||||
|
||||
public class DbElectionWin
|
||||
{
|
||||
public uint nhood_id { get; set; }
|
||||
public string nhood_name { get; set; }
|
||||
}
|
||||
}
|
285
server/FSO.Server.Database/DA/Elections/SqlElections.cs
Executable file
285
server/FSO.Server.Database/DA/Elections/SqlElections.cs
Executable file
|
@ -0,0 +1,285 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Dapper;
|
||||
using FSO.Server.Common;
|
||||
|
||||
namespace FSO.Server.Database.DA.Elections
|
||||
{
|
||||
public class SqlElections : AbstractSqlDA, IElections
|
||||
{
|
||||
public SqlElections(ISqlContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public DbElectionCandidate GetCandidate(uint avatar_id, uint cycle_id, DbCandidateState state)
|
||||
{
|
||||
return Context.Connection.Query<DbElectionCandidate>("SELECT * FROM fso_election_candidates WHERE candidate_avatar_id = @avatar_id " +
|
||||
"AND election_cycle_id = @cycle_id AND state = @state",
|
||||
new { avatar_id, cycle_id, state = state.ToString() }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public List<DbElectionCandidate> GetCandidates(uint cycle_id, DbCandidateState state)
|
||||
{
|
||||
return Context.Connection.Query<DbElectionCandidate>("SELECT * FROM fso_election_candidates WHERE election_cycle_id = @cycle_id AND state = @state",
|
||||
new { cycle_id, state = state.ToString() }).ToList();
|
||||
}
|
||||
|
||||
public List<DbElectionCandidate> GetCandidates(uint cycle_id)
|
||||
{
|
||||
return Context.Connection.Query<DbElectionCandidate>("SELECT * FROM fso_election_candidates WHERE election_cycle_id = @cycle_id",
|
||||
new { cycle_id }).ToList();
|
||||
}
|
||||
|
||||
public List<DbElectionCycle> GetActiveCycles(int shard_id)
|
||||
{
|
||||
|
||||
return Context.Connection.Query<DbElectionCycle>("SELECT *, n.neighborhood_id AS 'nhood_id' " +
|
||||
"FROM fso_election_cycles JOIN fso_neighborhoods n ON election_cycle_id = cycle_id " +
|
||||
"WHERE current_state != 'shutdown' " +
|
||||
"AND cycle_id IN (SELECT election_cycle_id FROM fso_neighborhoods WHERE shard_id = @shard_id)",
|
||||
new { shard_id }).ToList();
|
||||
}
|
||||
|
||||
public DbElectionCycle GetCycle(uint cycle_id)
|
||||
{
|
||||
return Context.Connection.Query<DbElectionCycle>("SELECT * FROM fso_election_cycles WHERE cycle_id = @cycle_id",
|
||||
new { cycle_id = cycle_id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public List<DbElectionVote> GetCycleVotes(uint cycle_id, DbElectionVoteType type)
|
||||
{
|
||||
return Context.Connection.Query<DbElectionVote>("SELECT * FROM fso_election_votes WHERE election_cycle_id = @cycle_id AND type = @type",
|
||||
new { cycle_id = cycle_id, type = type.ToString() }).ToList();
|
||||
}
|
||||
|
||||
public List<DbElectionVote> GetCycleVotesForAvatar(uint avatar_id, uint cycle_id, DbElectionVoteType type)
|
||||
{
|
||||
return Context.Connection.Query<DbElectionVote>("SELECT * FROM fso_election_votes WHERE election_cycle_id = @cycle_id AND type = @type "
|
||||
+ "AND target_avatar_id = @avatar_id",
|
||||
new { avatar_id = avatar_id, cycle_id = cycle_id, type = type.ToString() }).ToList();
|
||||
}
|
||||
|
||||
public DbElectionVote GetMyVote(uint avatar_id, uint cycle_id, DbElectionVoteType type)
|
||||
{
|
||||
//this isn't as straightforward as you might think.
|
||||
//we also need to include votes from:
|
||||
// - other sims on our user
|
||||
// - other sims on other users that share login ip
|
||||
//note that this criteria is duplicated in the database in the form of a BEFORE INSERT check.
|
||||
|
||||
var query = "SELECT * from fso_election_votes v INNER JOIN fso_avatars va ON v.from_avatar_id = va.avatar_id " +
|
||||
"WHERE v.election_cycle_id = @cycle_id AND v.type = @type AND va.user_id IN " +
|
||||
"(SELECT user_id FROM fso_users WHERE last_ip = " +
|
||||
"(SELECT last_ip FROM fso_avatars a JOIN fso_users u on a.user_id = u.user_id WHERE avatar_id = @avatar_id)" +
|
||||
")";
|
||||
|
||||
return Context.Connection.Query<DbElectionVote>(query,
|
||||
new { avatar_id = avatar_id, cycle_id = cycle_id, type = type.ToString() }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public bool CreateCandidate(DbElectionCandidate candidate)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = Context.Connection.Execute("INSERT INTO fso_election_candidates (election_cycle_id, candidate_avatar_id, comment) "
|
||||
+ "VALUES (@election_cycle_id, @candidate_avatar_id, @comment)", candidate);
|
||||
return (result > 0);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool SetCandidateState(DbElectionCandidate candidate)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = Context.Connection.Execute("UPDATE fso_election_candidates SET state = @state, comment = @comment " +
|
||||
"WHERE election_cycle_id = @election_cycle_id AND candidate_avatar_id = @candidate_avatar_id"
|
||||
, new { state = candidate.state.ToString(), candidate.comment,
|
||||
candidate.election_cycle_id, candidate.candidate_avatar_id});
|
||||
return (result > 0);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool DeleteCandidate(uint election_cycle_id, uint candidate_avatar_id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = Context.Connection.Execute("DELETE FROM fso_election_candidates " +
|
||||
"WHERE election_cycle_id = @election_cycle_id AND candidate_avatar_id = @candidate_avatar_id",
|
||||
new { election_cycle_id = election_cycle_id, candidate_avatar_id = candidate_avatar_id });
|
||||
return (result > 0);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public uint CreateCycle(DbElectionCycle cycle)
|
||||
{
|
||||
var result = Context.Connection.Query<uint>("INSERT INTO fso_election_cycles (start_date, end_date, current_state, election_type) "
|
||||
+ "VALUES (@start_date, @end_date, @current_state, @election_type); SELECT LAST_INSERT_ID();",
|
||||
new { cycle.start_date, cycle.end_date,
|
||||
current_state = cycle.current_state.ToString(),
|
||||
election_type = cycle.election_type.ToString() }).FirstOrDefault();
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool CreateVote(DbElectionVote vote)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = Context.Connection.Execute("INSERT INTO fso_election_votes (election_cycle_id, from_avatar_id, type, target_avatar_id, date) "
|
||||
+ "VALUES (@election_cycle_id, @from_avatar_id, @type, @target_avatar_id, @date)", new
|
||||
{
|
||||
vote.election_cycle_id,
|
||||
vote.from_avatar_id,
|
||||
type = vote.type.ToString(),
|
||||
vote.target_avatar_id,
|
||||
vote.date
|
||||
});
|
||||
return (result > 0);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateCycleState(uint cycle_id, DbElectionCycleState state)
|
||||
{
|
||||
Context.Connection.Query<DbElectionVote>("UPDATE fso_election_cycles SET current_state = @state WHERE cycle_id = @cycle_id",
|
||||
new { cycle_id = cycle_id, state = state.ToString() }).ToList();
|
||||
}
|
||||
|
||||
public DbMayorRating GetSpecificRating(uint from_user_id, uint to_avatar_id)
|
||||
{
|
||||
return Context.Connection.Query<DbMayorRating>("SELECT * FROM fso_mayor_ratings WHERE from_user_id = @from_user_id "
|
||||
+ "AND to_avatar_id = @to_avatar_id",
|
||||
new { from_user_id = from_user_id, to_avatar_id = to_avatar_id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public DbMayorRating GetRating(uint rating_id)
|
||||
{
|
||||
return Context.Connection.Query<DbMayorRating>("SELECT * FROM fso_mayor_ratings WHERE rating_id = @rating_id ",
|
||||
new { rating_id = rating_id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
|
||||
public List<uint> GetRatings(uint to_avatar_id)
|
||||
{
|
||||
return Context.Connection.Query<uint>("SELECT rating_id FROM fso_mayor_ratings WHERE to_avatar_id = @to_avatar_id ORDER BY rating",
|
||||
new { to_avatar_id = to_avatar_id }).ToList();
|
||||
}
|
||||
|
||||
public float? GetAvgRating(uint to_avatar_id)
|
||||
{
|
||||
return Context.Connection.Query<float?>("SELECT AVG(CAST(rating as DECIMAL(10,6))) FROM fso_mayor_ratings WHERE to_avatar_id = @to_avatar_id",
|
||||
new { to_avatar_id = to_avatar_id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public uint SetRating(DbMayorRating rating)
|
||||
{
|
||||
//first let's try insert our rating.
|
||||
try
|
||||
{
|
||||
var result = Context.Connection.Execute("INSERT INTO fso_mayor_ratings (from_user_id, to_user_id, rating, comment, "
|
||||
+ "date, from_avatar_id, to_avatar_id, anonymous, neighborhood) "
|
||||
+ "VALUES (@from_user_id, @to_user_id, @rating, @comment, "
|
||||
+ "@date, @from_avatar_id, @to_avatar_id, @anonymous, @neighborhood)", rating);
|
||||
return 0;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//didn't work? probably because the rating is already there. try updating instead.
|
||||
|
||||
Context.Connection.Execute("UPDATE fso_mayor_ratings SET rating = @rating, comment = @comment, date = @date "
|
||||
+ "WHERE from_user_id = @from_user_id AND to_user_id = @to_user_id", rating);
|
||||
|
||||
var id = Context.Connection.Query<uint>("SELECT rating_id FROM fso_mayor_ratings WHERE from_user_id = @from_user_id "
|
||||
+ "AND to_user_id = @to_user_id", rating).FirstOrDefault();
|
||||
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
public bool DeleteRating(uint id)
|
||||
{
|
||||
var result = Context.Connection.Execute("DELETE FROM fso_mayor_ratings " +
|
||||
"WHERE rating_id = @id", new { id = id });
|
||||
return (result > 0);
|
||||
}
|
||||
|
||||
public bool EmailRegistered(DbElectionCycleMail p)
|
||||
{
|
||||
return Context.Connection.Query<int>("SELECT count(*) FROM fso_election_cyclemail WHERE cycle_id = @cycle_id AND avatar_id = @avatar_id AND cycle_state = @cycle_state",
|
||||
new { p.avatar_id, p.cycle_id, cycle_state = p.cycle_state.ToString() }).First() > 0;
|
||||
}
|
||||
|
||||
public bool TryRegisterMail(DbElectionCycleMail p)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Context.Connection.Execute("INSERT INTO fso_election_cyclemail (cycle_id, avatar_id, cycle_state) VALUES (@cycle_id, @avatar_id, @cycle_state)",
|
||||
new { p.avatar_id, p.cycle_id, cycle_state = p.cycle_state.ToString() }) > 0);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//already exists, or foreign key fails
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool EnrollFreeVote(DbElectionFreeVote entry)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Context.Connection.Execute("INSERT INTO fso_election_freevotes (avatar_id, neighborhood_id, cycle_id, date, expire_date) " +
|
||||
"VALUES (@avatar_id, @neighborhood_id, @cycle_id, @date, @expire_date)",
|
||||
entry) > 0);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//already exists, or foreign key fails
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public DbElectionFreeVote GetFreeVote(uint avatar_id)
|
||||
{
|
||||
var result = Context.Connection.Query<DbElectionFreeVote>("SELECT * FROM fso_election_freevotes WHERE avatar_id = @avatar_id",
|
||||
new { avatar_id }).FirstOrDefault();
|
||||
if (result != null && result.expire_date < Epoch.Now)
|
||||
{
|
||||
//outdated. delete and set null.
|
||||
try
|
||||
{
|
||||
Context.Connection.Execute("DELETE FROM fso_election_freevotes WHERE avatar_id = @avatar_id", new { avatar_id });
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public DbElectionWin FindLastWin(uint avatar_id)
|
||||
{
|
||||
return Context.Connection.Query<DbElectionWin>("SELECT n.neighborhood_id AS nhood_id, n.name AS nhood_name " +
|
||||
"FROM (fso_election_candidates e JOIN fso_election_cycles c ON e.election_cycle_id = c.cycle_id) " +
|
||||
"JOIN fso_neighborhoods n ON c.neighborhood_id = n.neighborhood_id " +
|
||||
"WHERE e.candidate_avatar_id = @avatar_id AND state = 'won' " +
|
||||
"ORDER BY e.election_cycle_id DESC LIMIT 1",
|
||||
new { avatar_id = avatar_id }).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
32
server/FSO.Server.Database/DA/EmailConfirmations/EmailConfirmation.cs
Executable file
32
server/FSO.Server.Database/DA/EmailConfirmations/EmailConfirmation.cs
Executable file
|
@ -0,0 +1,32 @@
|
|||
namespace FSO.Server.Database.DA.EmailConfirmation
|
||||
{
|
||||
/// <summary>
|
||||
/// EmailConfirmation model
|
||||
/// </summary>
|
||||
public class EmailConfirmation
|
||||
{
|
||||
/// <summary>
|
||||
/// Confirmation type. Can be an email confirmation or password
|
||||
/// reset confirmation.
|
||||
/// </summary>
|
||||
public ConfirmationType type { get; set; }
|
||||
/// <summary>
|
||||
/// The user email address.
|
||||
/// </summary>
|
||||
public string email { get; set; }
|
||||
/// <summary>
|
||||
/// Randomized token.
|
||||
/// </summary>
|
||||
public string token { get; set; }
|
||||
/// <summary>
|
||||
/// Timestamp when the confirmation token will expire.
|
||||
/// </summary>
|
||||
public uint expires { get; set; }
|
||||
}
|
||||
|
||||
public enum ConfirmationType
|
||||
{
|
||||
email = 1,
|
||||
password
|
||||
}
|
||||
}
|
10
server/FSO.Server.Database/DA/EmailConfirmations/IEmailConfirmations.cs
Executable file
10
server/FSO.Server.Database/DA/EmailConfirmations/IEmailConfirmations.cs
Executable file
|
@ -0,0 +1,10 @@
|
|||
namespace FSO.Server.Database.DA.EmailConfirmation
|
||||
{
|
||||
public interface IEmailConfirmations
|
||||
{
|
||||
string Create(EmailConfirmation confirm);
|
||||
EmailConfirmation GetByEmail(string email, ConfirmationType type);
|
||||
EmailConfirmation GetByToken(string token);
|
||||
void Remove(string token);
|
||||
}
|
||||
}
|
57
server/FSO.Server.Database/DA/EmailConfirmations/SqlEmailConfirmations.cs
Executable file
57
server/FSO.Server.Database/DA/EmailConfirmations/SqlEmailConfirmations.cs
Executable file
|
@ -0,0 +1,57 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Dapper;
|
||||
using FSO.Server.Common;
|
||||
|
||||
namespace FSO.Server.Database.DA.EmailConfirmation
|
||||
{
|
||||
public class SqlEmailConfirmations : AbstractSqlDA, IEmailConfirmations
|
||||
{
|
||||
public SqlEmailConfirmations(ISqlContext context) : base(context)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public EmailConfirmation GetByToken(string token)
|
||||
{
|
||||
var confirm = Context.Connection.Query<EmailConfirmation>("SELECT * FROM fso_email_confirm WHERE token = @token", new { token = token }).FirstOrDefault();
|
||||
|
||||
if(confirm==null) { return null; }
|
||||
|
||||
if(Epoch.Now > confirm.expires)
|
||||
{
|
||||
Remove(confirm.token);
|
||||
return null;
|
||||
}
|
||||
|
||||
return confirm;
|
||||
}
|
||||
|
||||
public EmailConfirmation GetByEmail(string email, ConfirmationType type)
|
||||
{
|
||||
var confirm = Context.Connection.Query<EmailConfirmation>("SELECT * FROM fso_email_confirm WHERE email = @email AND type = @type", new { email = email, type = type }).FirstOrDefault();
|
||||
|
||||
if (confirm == null) { return null; }
|
||||
|
||||
if (Epoch.Now > confirm.expires)
|
||||
{
|
||||
Remove(confirm.token);
|
||||
return null;
|
||||
}
|
||||
|
||||
return confirm;
|
||||
}
|
||||
|
||||
public string Create(EmailConfirmation confirm)
|
||||
{
|
||||
confirm.token = Guid.NewGuid().ToString().ToUpper();
|
||||
Context.Connection.Execute("INSERT INTO fso_email_confirm (type, email, token, expires) VALUES (@type, @email, @token, @expires)", confirm);
|
||||
return confirm.token;
|
||||
}
|
||||
|
||||
public void Remove(string token)
|
||||
{
|
||||
Context.Connection.Execute("DELETE FROM fso_email_confirm WHERE token = @token", new { token = token });
|
||||
}
|
||||
}
|
||||
}
|
13
server/FSO.Server.Database/DA/GlobalCooldowns/DbGlobalCooldowns.cs
Executable file
13
server/FSO.Server.Database/DA/GlobalCooldowns/DbGlobalCooldowns.cs
Executable file
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
|
||||
namespace FSO.Server.Database.DA.GlobalCooldowns
|
||||
{
|
||||
public class DbGlobalCooldowns
|
||||
{
|
||||
public uint object_guid { get; set; }
|
||||
public uint avatar_id { get; set; }
|
||||
public uint user_id { get; set; }
|
||||
public uint category { get; set; }
|
||||
public DateTime expiry { get; set; }
|
||||
}
|
||||
}
|
14
server/FSO.Server.Database/DA/GlobalCooldowns/IGlobalCooldowns.cs
Executable file
14
server/FSO.Server.Database/DA/GlobalCooldowns/IGlobalCooldowns.cs
Executable file
|
@ -0,0 +1,14 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.GlobalCooldowns
|
||||
{
|
||||
public interface IGlobalCooldowns
|
||||
{
|
||||
DbGlobalCooldowns Get(uint objguid, uint avatarid, bool useAccount, uint category);
|
||||
List<DbGlobalCooldowns> GetAllByObj(uint objguid);
|
||||
List<DbGlobalCooldowns> GetAllByAvatar(uint avatarid);
|
||||
List<DbGlobalCooldowns> GetAllByObjectAndAvatar(uint objguid, uint avatarid);
|
||||
bool Create(DbGlobalCooldowns cooldown);
|
||||
bool Update(DbGlobalCooldowns cooldown);
|
||||
}
|
||||
}
|
49
server/FSO.Server.Database/DA/GlobalCooldowns/SqlGlobalCooldowns.cs
Executable file
49
server/FSO.Server.Database/DA/GlobalCooldowns/SqlGlobalCooldowns.cs
Executable file
|
@ -0,0 +1,49 @@
|
|||
using Dapper;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace FSO.Server.Database.DA.GlobalCooldowns
|
||||
{
|
||||
public class SqlGlobalCooldowns : AbstractSqlDA, IGlobalCooldowns
|
||||
{
|
||||
public SqlGlobalCooldowns(ISqlContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public DbGlobalCooldowns Get(uint objguid, uint avatarOrUserid, bool useAccount, uint category)
|
||||
{
|
||||
if (useAccount)
|
||||
return Context.Connection.Query<DbGlobalCooldowns>("SELECT * FROM fso_global_cooldowns WHERE object_guid = @guid AND " +
|
||||
"user_id = @id AND category = @category", new { guid = objguid, id = avatarOrUserid, category = category }).FirstOrDefault();
|
||||
else
|
||||
return Context.Connection.Query<DbGlobalCooldowns>("SELECT * FROM fso_global_cooldowns WHERE object_guid = @guid AND " +
|
||||
"avatar_id = @id AND category = @category", new { guid = objguid, id = avatarOrUserid, category = category }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public List<DbGlobalCooldowns> GetAllByObj(uint objguid)
|
||||
{
|
||||
return Context.Connection.Query<DbGlobalCooldowns>("SELECT * FROM fso_global_cooldowns WHERE object_guid = @guid", new { guid = objguid }).ToList();
|
||||
}
|
||||
|
||||
public List<DbGlobalCooldowns> GetAllByAvatar(uint avatarid)
|
||||
{
|
||||
return Context.Connection.Query<DbGlobalCooldowns>("SELECT * FROM fso_global_cooldowns WHERE avatar_id = @avatarid", new { avatarid = avatarid }).ToList();
|
||||
}
|
||||
|
||||
public List<DbGlobalCooldowns> GetAllByObjectAndAvatar(uint objguid, uint avatarid)
|
||||
{
|
||||
return Context.Connection.Query<DbGlobalCooldowns>("SELECT * FROM fso_global_cooldowns WHERE object_guid = @guid AND " +
|
||||
"avatar_id = @avatarid", new { guid = objguid, avatarid = avatarid }).ToList();
|
||||
}
|
||||
public bool Create(DbGlobalCooldowns newCooldown)
|
||||
{
|
||||
return Context.Connection.Execute("INSERT INTO fso_global_cooldowns (object_guid, avatar_id, user_id, category, expiry) " +
|
||||
"VALUES (@object_guid, @avatar_id, @user_id, @category, @expiry)", newCooldown) > 0;
|
||||
}
|
||||
public bool Update(DbGlobalCooldowns updatedCooldown)
|
||||
{
|
||||
return Context.Connection.Execute("UPDATE fso_global_cooldowns SET expiry = @expiry WHERE object_guid = @object_guid AND " +
|
||||
"avatar_id = @avatar_id AND user_id = @user_id AND category = @category", updatedCooldown) > 0;
|
||||
}
|
||||
}
|
||||
}
|
28
server/FSO.Server.Database/DA/Hosts/DbHost.cs
Executable file
28
server/FSO.Server.Database/DA/Hosts/DbHost.cs
Executable file
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
|
||||
namespace FSO.Server.Database.DA.Hosts
|
||||
{
|
||||
public class DbHost
|
||||
{
|
||||
public string call_sign { get; set; }
|
||||
public DbHostRole role { get; set; }
|
||||
public DbHostStatus status { get; set; }
|
||||
public string internal_host { get; set; }
|
||||
public string public_host { get; set; }
|
||||
public DateTime time_boot { get; set; }
|
||||
public int? shard_id { get; set; }
|
||||
}
|
||||
|
||||
public enum DbHostRole
|
||||
{
|
||||
city,
|
||||
lot,
|
||||
task
|
||||
}
|
||||
|
||||
public enum DbHostStatus
|
||||
{
|
||||
up,
|
||||
down
|
||||
}
|
||||
}
|
12
server/FSO.Server.Database/DA/Hosts/IHosts.cs
Executable file
12
server/FSO.Server.Database/DA/Hosts/IHosts.cs
Executable file
|
@ -0,0 +1,12 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Hosts
|
||||
{
|
||||
public interface IHosts
|
||||
{
|
||||
IEnumerable<DbHost> All();
|
||||
DbHost Get(string call_sign);
|
||||
void CreateHost(DbHost host);
|
||||
void SetStatus(string call_sign, DbHostStatus status);
|
||||
}
|
||||
}
|
49
server/FSO.Server.Database/DA/Hosts/SqlHosts.cs
Executable file
49
server/FSO.Server.Database/DA/Hosts/SqlHosts.cs
Executable file
|
@ -0,0 +1,49 @@
|
|||
using Dapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Hosts
|
||||
{
|
||||
public class SqlHosts : AbstractSqlDA, IHosts
|
||||
{
|
||||
public SqlHosts(ISqlContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public IEnumerable<DbHost> All()
|
||||
{
|
||||
return Context.Connection.Query<DbHost>("SELECT * FROM fso_hosts");
|
||||
}
|
||||
|
||||
public void CreateHost(DbHost host)
|
||||
{
|
||||
Context.Connection.Execute(
|
||||
"REPLACE INTO fso_hosts (call_sign, role, status, internal_host, public_host, time_boot, shard_id) " +
|
||||
"VALUES (@call_sign, @role, @status, @internal_host, @public_host, @time_boot, @shard_id)",
|
||||
new
|
||||
{
|
||||
call_sign = host.call_sign,
|
||||
role = host.role.ToString(),
|
||||
status = host.status.ToString(),
|
||||
internal_host = host.internal_host,
|
||||
public_host = host.public_host,
|
||||
time_boot = host.time_boot,
|
||||
shard_id = host.shard_id
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public DbHost Get(string call_sign)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetStatus(string call_sign, DbHostStatus status)
|
||||
{
|
||||
Context.Connection.Execute("UPDATE fso_hosts SET status = @status WHERE call_sign = @call_sign", new {
|
||||
call_sign = call_sign,
|
||||
status = status.ToString()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
73
server/FSO.Server.Database/DA/IDA.cs
Executable file
73
server/FSO.Server.Database/DA/IDA.cs
Executable file
|
@ -0,0 +1,73 @@
|
|||
using FSO.Server.Database.DA.AuthTickets;
|
||||
using FSO.Server.Database.DA.AvatarClaims;
|
||||
using FSO.Server.Database.DA.Avatars;
|
||||
using FSO.Server.Database.DA.Bans;
|
||||
using FSO.Server.Database.DA.Bonus;
|
||||
using FSO.Server.Database.DA.Bookmarks;
|
||||
using FSO.Server.Database.DA.DbEvents;
|
||||
using FSO.Server.Database.DA.Hosts;
|
||||
using FSO.Server.Database.DA.Inbox;
|
||||
using FSO.Server.Database.DA.LotAdmit;
|
||||
using FSO.Server.Database.DA.LotClaims;
|
||||
using FSO.Server.Database.DA.Lots;
|
||||
using FSO.Server.Database.DA.LotTop100;
|
||||
using FSO.Server.Database.DA.LotVisitors;
|
||||
using FSO.Server.Database.DA.LotVisitTotals;
|
||||
using FSO.Server.Database.DA.Objects;
|
||||
using FSO.Server.Database.DA.Outfits;
|
||||
using FSO.Server.Database.DA.Relationships;
|
||||
using FSO.Server.Database.DA.Roommates;
|
||||
using FSO.Server.Database.DA.Shards;
|
||||
using FSO.Server.Database.DA.Tasks;
|
||||
using FSO.Server.Database.DA.Users;
|
||||
using FSO.Server.Database.DA.Tuning;
|
||||
using System;
|
||||
using FSO.Server.Database.DA.Transactions;
|
||||
using FSO.Server.Database.DA.DynPayouts;
|
||||
using FSO.Server.Database.DA.EmailConfirmation;
|
||||
using FSO.Server.Database.DA.Neighborhoods;
|
||||
using FSO.Server.Database.DA.Elections;
|
||||
using FSO.Server.Database.DA.Bulletin;
|
||||
using FSO.Server.Database.DA.Updates;
|
||||
using FSO.Server.Database.DA.GlobalCooldowns;
|
||||
|
||||
namespace FSO.Server.Database.DA
|
||||
{
|
||||
public interface IDA : IDisposable
|
||||
{
|
||||
IUsers Users { get; }
|
||||
IBans Bans { get; }
|
||||
IAuthTickets AuthTickets { get; }
|
||||
IShards Shards { get; }
|
||||
IAvatars Avatars { get; }
|
||||
IObjects Objects { get; }
|
||||
IRelationships Relationships { get; }
|
||||
IRoommates Roommates { get; }
|
||||
ILots Lots { get; }
|
||||
ILotAdmit LotAdmit { get; }
|
||||
ILotClaims LotClaims { get; }
|
||||
INeighborhoods Neighborhoods { get; }
|
||||
IElections Elections { get; }
|
||||
IBulletinPosts BulletinPosts { get; }
|
||||
IAvatarClaims AvatarClaims { get; }
|
||||
IBookmarks Bookmarks { get; }
|
||||
IOutfits Outfits { get; }
|
||||
ILotVisits LotVisits { get; }
|
||||
ILotVisitTotals LotVisitTotals { get; }
|
||||
ILotTop100 LotTop100 { get; }
|
||||
IBonus Bonus { get; }
|
||||
IInbox Inbox { get; }
|
||||
IEvents Events { get; }
|
||||
ITuning Tuning { get; }
|
||||
IDynPayouts DynPayouts { get; }
|
||||
ITransactions Transactions { get; }
|
||||
|
||||
//System tables
|
||||
IHosts Hosts { get; }
|
||||
ITasks Tasks { get; }
|
||||
IEmailConfirmations EmailConfirmations { get; }
|
||||
IUpdates Updates { get; }
|
||||
IGlobalCooldowns GlobalCooldowns { get; }
|
||||
void Flush();
|
||||
}
|
||||
}
|
7
server/FSO.Server.Database/DA/IDAFactory.cs
Executable file
7
server/FSO.Server.Database/DA/IDAFactory.cs
Executable file
|
@ -0,0 +1,7 @@
|
|||
namespace FSO.Server.Database.DA
|
||||
{
|
||||
public interface IDAFactory
|
||||
{
|
||||
IDA Get();
|
||||
}
|
||||
}
|
11
server/FSO.Server.Database/DA/ISqlContext.cs
Executable file
11
server/FSO.Server.Database/DA/ISqlContext.cs
Executable file
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Data.Common;
|
||||
|
||||
namespace FSO.Server.Database.DA
|
||||
{
|
||||
public interface ISqlContext : IDisposable
|
||||
{
|
||||
DbConnection Connection { get; }
|
||||
void Flush();
|
||||
}
|
||||
}
|
19
server/FSO.Server.Database/DA/Inbox/DbInboxMsg.cs
Executable file
19
server/FSO.Server.Database/DA/Inbox/DbInboxMsg.cs
Executable file
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
|
||||
namespace FSO.Server.Database.DA.Inbox
|
||||
{
|
||||
public class DbInboxMsg
|
||||
{
|
||||
public int message_id { get; set; }
|
||||
public uint sender_id { get; set; }
|
||||
public uint target_id { get; set; }
|
||||
public string subject { get; set; }
|
||||
public string body { get; set; }
|
||||
public string sender_name { get; set; }
|
||||
public DateTime time { get; set; }
|
||||
public int msg_type { get; set; }
|
||||
public int msg_subtype { get; set; }
|
||||
public int read_state { get; set; }
|
||||
public int? reply_id { get; set; }
|
||||
}
|
||||
}
|
15
server/FSO.Server.Database/DA/Inbox/IInbox.cs
Executable file
15
server/FSO.Server.Database/DA/Inbox/IInbox.cs
Executable file
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Inbox
|
||||
{
|
||||
public interface IInbox
|
||||
{
|
||||
List<DbInboxMsg> GetMessages(uint avatarID);
|
||||
List<DbInboxMsg> GetMessagesAfter(uint avatarID, DateTime after);
|
||||
DbInboxMsg Get(int msgID);
|
||||
int CreateMessage(DbInboxMsg msg);
|
||||
bool DeleteMessage(int msgID, uint avatarID);
|
||||
bool DeleteMessage(int msgID);
|
||||
}
|
||||
}
|
47
server/FSO.Server.Database/DA/Inbox/SqlInbox.cs
Executable file
47
server/FSO.Server.Database/DA/Inbox/SqlInbox.cs
Executable file
|
@ -0,0 +1,47 @@
|
|||
using Dapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace FSO.Server.Database.DA.Inbox
|
||||
{
|
||||
public class SqlInbox : AbstractSqlDA, IInbox
|
||||
{
|
||||
public SqlInbox(ISqlContext context) : base(context){
|
||||
}
|
||||
|
||||
public int CreateMessage(DbInboxMsg msg)
|
||||
{
|
||||
var result = Context.Connection.Query<int>("INSERT INTO fso_inbox (sender_id, target_id, subject, " +
|
||||
"body, sender_name, time, msg_type, msg_subtype, read_state) " +
|
||||
" VALUES (@sender_id, @target_id, @subject, @body, @sender_name, " +
|
||||
" @time, @msg_type, @msg_subtype, @read_state); SELECT LAST_INSERT_ID();", msg).First();
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool DeleteMessage(int msgID)
|
||||
{
|
||||
return Context.Connection.Execute("DELETE FROM fso_inbox WHERE message_id = @id", new { id = msgID }) > 0;
|
||||
}
|
||||
|
||||
public bool DeleteMessage(int msgID, uint avatarID)
|
||||
{
|
||||
return Context.Connection.Execute("DELETE FROM fso_inbox WHERE message_id = @id AND target_id = @aid", new { id = msgID, aid = avatarID }) > 0;
|
||||
}
|
||||
|
||||
public DbInboxMsg Get(int msgID)
|
||||
{
|
||||
return Context.Connection.Query<DbInboxMsg>("SELECT * FROM fso_inbox WHERE message_id = @id", new { id = msgID }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public List<DbInboxMsg> GetMessages(uint avatarID)
|
||||
{
|
||||
return Context.Connection.Query<DbInboxMsg>("SELECT * FROM fso_inbox WHERE target_id = @id", new { id = avatarID }).ToList();
|
||||
}
|
||||
|
||||
public List<DbInboxMsg> GetMessagesAfter(uint avatarID, DateTime after)
|
||||
{
|
||||
return Context.Connection.Query<DbInboxMsg>("SELECT * FROM fso_inbox WHERE target_id = @id AND time > @after", new { id = avatarID, after = after }).ToList();
|
||||
}
|
||||
}
|
||||
}
|
9
server/FSO.Server.Database/DA/LotAdmit/DbLotAdmit.cs
Executable file
9
server/FSO.Server.Database/DA/LotAdmit/DbLotAdmit.cs
Executable file
|
@ -0,0 +1,9 @@
|
|||
namespace FSO.Server.Database.DA.LotAdmit
|
||||
{
|
||||
public class DbLotAdmit
|
||||
{
|
||||
public int lot_id { get; set; }
|
||||
public uint avatar_id { get; set; }
|
||||
public byte admit_type { get; set; }
|
||||
}
|
||||
}
|
12
server/FSO.Server.Database/DA/LotAdmit/ILotAdmit.cs
Executable file
12
server/FSO.Server.Database/DA/LotAdmit/ILotAdmit.cs
Executable file
|
@ -0,0 +1,12 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.LotAdmit
|
||||
{
|
||||
public interface ILotAdmit
|
||||
{
|
||||
List<DbLotAdmit> GetLotInfo(int lot_id);
|
||||
List<uint> GetLotAdmitDeny(int lot_id, byte admit_mode);
|
||||
void Create(DbLotAdmit bookmark);
|
||||
bool Delete(DbLotAdmit bookmark);
|
||||
}
|
||||
}
|
35
server/FSO.Server.Database/DA/LotAdmit/SqlLotAdmit.cs
Executable file
35
server/FSO.Server.Database/DA/LotAdmit/SqlLotAdmit.cs
Executable file
|
@ -0,0 +1,35 @@
|
|||
using Dapper;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace FSO.Server.Database.DA.LotAdmit
|
||||
{
|
||||
public class SqlLotAdmit : AbstractSqlDA, ILotAdmit
|
||||
{
|
||||
public SqlLotAdmit(ISqlContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public void Create(DbLotAdmit bookmark)
|
||||
{
|
||||
Context.Connection.Execute("INSERT INTO fso_lot_admit (lot_id, avatar_id, admit_type) " +
|
||||
" VALUES (@lot_id, @avatar_id, @admit_type)"
|
||||
, bookmark);
|
||||
}
|
||||
|
||||
public bool Delete(DbLotAdmit bookmark)
|
||||
{
|
||||
return Context.Connection.Execute("DELETE FROM fso_lot_admit WHERE lot_id = @lot_id AND admit_type = @admit_type AND avatar_id = @avatar_id", bookmark) > 0;
|
||||
}
|
||||
|
||||
public List<DbLotAdmit> GetLotInfo(int lot_id)
|
||||
{
|
||||
return Context.Connection.Query<DbLotAdmit>("SELECT * FROM fso_lot_admit WHERE lot_id = @lot_id", new { lot_id = lot_id }).ToList();
|
||||
}
|
||||
|
||||
public List<uint> GetLotAdmitDeny(int lot_id, byte admit_type)
|
||||
{
|
||||
return Context.Connection.Query<uint>("SELECT avatar_id FROM fso_lot_admit WHERE lot_id = @lot_id AND admit_type = @admit_type", new { lot_id = lot_id, admit_type = admit_type }).ToList();
|
||||
}
|
||||
}
|
||||
}
|
29
server/FSO.Server.Database/DA/LotClaims/DbLotClaim.cs
Executable file
29
server/FSO.Server.Database/DA/LotClaims/DbLotClaim.cs
Executable file
|
@ -0,0 +1,29 @@
|
|||
namespace FSO.Server.Database.DA.LotClaims
|
||||
{
|
||||
public class DbLotClaim
|
||||
{
|
||||
public int claim_id { get; set; }
|
||||
public int shard_id { get; set; }
|
||||
public int lot_id { get; set; }
|
||||
public string owner { get; set; }
|
||||
}
|
||||
|
||||
public class DbLotStatus
|
||||
{
|
||||
public uint location { get; set; }
|
||||
public int active { get; set; }
|
||||
}
|
||||
|
||||
public class DbLotActive
|
||||
{
|
||||
public int lot_id { get; set; }
|
||||
public int shard_id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string description { get; set; }
|
||||
public uint location { get; set; }
|
||||
public uint neighborhood_id { get; set; }
|
||||
public uint admit_mode { get; set; }
|
||||
public FSO.Common.Enum.LotCategory category { get; set; }
|
||||
public int active { get; set; }
|
||||
}
|
||||
}
|
22
server/FSO.Server.Database/DA/LotClaims/ILotClaims.cs
Executable file
22
server/FSO.Server.Database/DA/LotClaims/ILotClaims.cs
Executable file
|
@ -0,0 +1,22 @@
|
|||
using FSO.Common.Enum;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.LotClaims
|
||||
{
|
||||
public interface ILotClaims
|
||||
{
|
||||
uint? TryCreate(DbLotClaim claim);
|
||||
IEnumerable<DbLotClaim> GetAllByOwner(string owner);
|
||||
|
||||
bool Claim(uint id, string previousOwner, string newOwner);
|
||||
DbLotClaim Get(uint id);
|
||||
DbLotClaim GetByLotID(int id);
|
||||
|
||||
void RemoveAllByOwner(string owner);
|
||||
void Delete(uint id, string owner);
|
||||
List<DbLotStatus> AllLocations(int shardId);
|
||||
List<DbLotActive> AllActiveLots(int shardId);
|
||||
List<DbLotStatus> Top100Filter(int shard_id, LotCategory category, int limit);
|
||||
List<uint> RecentsFilter(uint avatar_id, int limit);
|
||||
}
|
||||
}
|
105
server/FSO.Server.Database/DA/LotClaims/SqlLotsClaims.cs
Executable file
105
server/FSO.Server.Database/DA/LotClaims/SqlLotsClaims.cs
Executable file
|
@ -0,0 +1,105 @@
|
|||
using Dapper;
|
||||
using FSO.Common.Enum;
|
||||
using MySql.Data.MySqlClient;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace FSO.Server.Database.DA.LotClaims
|
||||
{
|
||||
public class SqlLotClaims : AbstractSqlDA, ILotClaims
|
||||
{
|
||||
public SqlLotClaims(ISqlContext context) : base(context){
|
||||
}
|
||||
|
||||
public bool Claim(uint id, string previousOwner, string newOwner)
|
||||
{
|
||||
try
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_lot_claims SET owner = @owner WHERE claim_id = @claim_id AND owner = @previous_owner", new { claim_id = (int)id, previous_owner = previousOwner, owner = newOwner });
|
||||
var newClaim = Context.Connection.Query<DbLotClaim>("SELECT * FROM fso_lot_claims WHERE claim_id = @claim_id AND owner = @owner", new { claim_id = (int)id, owner = newOwner }).FirstOrDefault();
|
||||
return newClaim != null;
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete(uint id, string owner)
|
||||
{
|
||||
Context.Connection.Query("DELETE FROM fso_lot_claims WHERE owner = @owner AND claim_id = @claim_id", new { owner = owner, claim_id = (int)id });
|
||||
}
|
||||
|
||||
public DbLotClaim Get(uint id)
|
||||
{
|
||||
return Context.Connection.Query<DbLotClaim>("SELECT * FROM fso_lot_claims WHERE claim_id = @claim_id", new { claim_id = (int)id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public DbLotClaim GetByLotID(int id)
|
||||
{
|
||||
return Context.Connection.Query<DbLotClaim>("SELECT * FROM fso_lot_claims WHERE lot_id = @lot_id", new { lot_id = id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public IEnumerable<DbLotClaim> GetAllByOwner(string owner)
|
||||
{
|
||||
return Context.Connection.Query<DbLotClaim>("SELECT * FROM fso_lot_claims WHERE owner = @owner", new { owner = owner });
|
||||
}
|
||||
|
||||
public void RemoveAllByOwner(string owner)
|
||||
{
|
||||
Context.Connection.Query("DELETE FROM fso_lot_claims WHERE owner = @owner", new { owner = owner });
|
||||
}
|
||||
|
||||
public uint? TryCreate(DbLotClaim claim){
|
||||
|
||||
try {
|
||||
return (uint)Context.Connection.Query<int>("INSERT INTO fso_lot_claims (shard_id, lot_id, owner) " +
|
||||
" VALUES (@shard_id, @lot_id, @owner); SELECT LAST_INSERT_ID();", claim).First();
|
||||
}catch(MySqlException ex){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public List<DbLotStatus> AllLocations(int shard_id)
|
||||
{
|
||||
return Context.Connection.Query<DbLotStatus>("SELECT b.location AS location, active " +
|
||||
"FROM fso.fso_lot_claims AS a " +
|
||||
"JOIN fso.fso_lots AS b " +
|
||||
"ON a.lot_id = b.lot_id " +
|
||||
"JOIN(SELECT location, COUNT(*) as active FROM fso_avatar_claims GROUP BY location) AS c " +
|
||||
"ON b.location = c.location WHERE a.shard_id = @shard_id", new { shard_id = shard_id }).ToList();
|
||||
}
|
||||
|
||||
public List<DbLotActive> AllActiveLots(int shard_id)
|
||||
{
|
||||
return Context.Connection.Query<DbLotActive>("SELECT b.*, active "+
|
||||
"FROM fso.fso_lot_claims as a "+
|
||||
"right JOIN fso.fso_lots as b ON a.lot_id = b.lot_id "+
|
||||
"JOIN (select location, count(*) as active FROM fso.fso_avatar_claims group by location) as c "+
|
||||
"on b.location = c.location where a.shard_id = @shard_id", new { shard_id = shard_id }).ToList();
|
||||
}
|
||||
|
||||
public List<DbLotStatus> Top100Filter(int shard_id, LotCategory category, int limit)
|
||||
{
|
||||
return Context.Connection.Query<DbLotStatus>("SELECT b.location AS location, active " +
|
||||
"FROM fso.fso_lot_claims AS a " +
|
||||
"JOIN fso.fso_lots AS b " +
|
||||
"ON a.lot_id = b.lot_id " +
|
||||
"JOIN(SELECT location, COUNT(*) as active FROM fso_avatar_claims GROUP BY location) AS c " +
|
||||
"ON b.location = c.location WHERE a.shard_id = @shard_id " +
|
||||
"AND category = @category AND active > 0 " +
|
||||
"ORDER BY active DESC " +
|
||||
"LIMIT @limit", new { shard_id = shard_id, category = category.ToString(), limit = limit }).ToList();
|
||||
}
|
||||
|
||||
public List<uint> RecentsFilter(uint avatar_id, int limit)
|
||||
{
|
||||
return Context.Connection.Query<uint>("SELECT b.location " +
|
||||
"FROM fso_lot_visits a JOIN fso_lots b ON a.lot_id = b.lot_id " +
|
||||
"WHERE avatar_id = @avatar_id " +
|
||||
"GROUP BY a.lot_id " +
|
||||
"ORDER BY MAX(time_created) DESC " +
|
||||
"LIMIT @limit", new { avatar_id = avatar_id, limit = limit }).ToList();
|
||||
}
|
||||
}
|
||||
}
|
19
server/FSO.Server.Database/DA/LotTop100/DbLotTop100.cs
Executable file
19
server/FSO.Server.Database/DA/LotTop100/DbLotTop100.cs
Executable file
|
@ -0,0 +1,19 @@
|
|||
using FSO.Common.Enum;
|
||||
using System;
|
||||
|
||||
namespace FSO.Server.Database.DA.LotTop100
|
||||
{
|
||||
public class DbLotTop100
|
||||
{
|
||||
public LotCategory category { get; set; }
|
||||
public byte rank { get; set; }
|
||||
public int shard_id { get; set; }
|
||||
public int? lot_id { get; set; }
|
||||
public int? minutes { get; set; }
|
||||
public DateTime date { get; set; }
|
||||
|
||||
//Joins
|
||||
public string lot_name { get; set; }
|
||||
public uint? lot_location { get; set; }
|
||||
}
|
||||
}
|
15
server/FSO.Server.Database/DA/LotTop100/ILotTop100.cs
Executable file
15
server/FSO.Server.Database/DA/LotTop100/ILotTop100.cs
Executable file
|
@ -0,0 +1,15 @@
|
|||
using FSO.Common.Enum;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.LotTop100
|
||||
{
|
||||
public interface ILotTop100
|
||||
{
|
||||
void Replace(IEnumerable<DbLotTop100> values);
|
||||
IEnumerable<DbLotTop100> All();
|
||||
IEnumerable<DbLotTop100> GetAllByShard(int shard_id);
|
||||
IEnumerable<DbLotTop100> GetByCategory(int shard_id, LotCategory category);
|
||||
bool Calculate(DateTime date, int shard_id);
|
||||
}
|
||||
}
|
67
server/FSO.Server.Database/DA/LotTop100/SqlLotTop100.cs
Executable file
67
server/FSO.Server.Database/DA/LotTop100/SqlLotTop100.cs
Executable file
|
@ -0,0 +1,67 @@
|
|||
using Dapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FSO.Common.Enum;
|
||||
|
||||
namespace FSO.Server.Database.DA.LotTop100
|
||||
{
|
||||
public class SqlLotTop100 : AbstractSqlDA, ILotTop100
|
||||
{
|
||||
public SqlLotTop100(ISqlContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public IEnumerable<DbLotTop100> All()
|
||||
{
|
||||
return Context.Connection.Query<DbLotTop100>("SELECT top.*, l.name as lot_name, l.location as lot_location FROM fso_lot_top_100 top LEFT JOIN fso_lots l ON top.lot_id = l.lot_id");
|
||||
}
|
||||
|
||||
public bool Calculate(DateTime date, int shard_id)
|
||||
{
|
||||
try
|
||||
{
|
||||
Context.Connection.Execute("CALL fso_lot_top_100_calc_all(@date, @shard_id);", new { date = date, shard_id = shard_id });
|
||||
return true;
|
||||
}catch(Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public IEnumerable<DbLotTop100> GetAllByShard(int shard_id)
|
||||
{
|
||||
return Context.Connection.Query<DbLotTop100>("SELECT top.*, l.name as lot_name, l.location as lot_location FROM fso_lot_top_100 top LEFT JOIN fso_lots l ON top.lot_id = l.lot_id WHERE top.shard_id = @shard_id", new
|
||||
{
|
||||
shard_id = shard_id
|
||||
});
|
||||
}
|
||||
public IEnumerable<DbLotTop100> GetByCategory(int shard_id, LotCategory category)
|
||||
{
|
||||
return Context.Connection.Query<DbLotTop100>("SELECT top.*, l.name as lot_name, l.location as lot_location FROM fso_lot_top_100 top LEFT JOIN fso_lots l ON top.lot_id = l.lot_id WHERE top.category = @category AND top.shard_id = @shard_id", new
|
||||
{
|
||||
category = category.ToString(),
|
||||
shard_id = shard_id
|
||||
});
|
||||
}
|
||||
|
||||
public void Replace(IEnumerable<DbLotTop100> values)
|
||||
{
|
||||
try {
|
||||
var valuesConverted = values.Select(x => {
|
||||
return new
|
||||
{
|
||||
category = x.category.ToString(),
|
||||
rank = x.rank,
|
||||
shard_id = x.shard_id,
|
||||
lot_id = x.lot_id,
|
||||
minutes = x.minutes
|
||||
};
|
||||
});
|
||||
|
||||
Context.Connection.Execute("REPLACE INTO fso_lot_top_100 (category, rank, shard_id, lot_id, minutes) VALUES (@category, @rank, @shard_id, @lot_id, @minutes)", valuesConverted);
|
||||
}catch(Exception ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
server/FSO.Server.Database/DA/LotVisitTotals/DbLotVisitTotal.cs
Executable file
11
server/FSO.Server.Database/DA/LotVisitTotals/DbLotVisitTotal.cs
Executable file
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace FSO.Server.Database.DA.LotVisitTotals
|
||||
{
|
||||
public class DbLotVisitTotal
|
||||
{
|
||||
public int lot_id { get; set; }
|
||||
public DateTime date { get; set; }
|
||||
public int minutes { get; set; }
|
||||
}
|
||||
}
|
11
server/FSO.Server.Database/DA/LotVisitTotals/ILotVisitTotals.cs
Executable file
11
server/FSO.Server.Database/DA/LotVisitTotals/ILotVisitTotals.cs
Executable file
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.LotVisitTotals
|
||||
{
|
||||
public interface ILotVisitTotals
|
||||
{
|
||||
void Insert(IEnumerable<DbLotVisitTotal> input);
|
||||
void Purge(DateTime date);
|
||||
}
|
||||
}
|
28
server/FSO.Server.Database/DA/LotVisitTotals/SqlLotVisitTotals.cs
Executable file
28
server/FSO.Server.Database/DA/LotVisitTotals/SqlLotVisitTotals.cs
Executable file
|
@ -0,0 +1,28 @@
|
|||
using Dapper;
|
||||
using FSO.Server.Database.DA.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.LotVisitTotals
|
||||
{
|
||||
public class SqlLotVisitTotals : AbstractSqlDA, ILotVisitTotals
|
||||
{
|
||||
public SqlLotVisitTotals(ISqlContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public void Insert(IEnumerable<DbLotVisitTotal> input)
|
||||
{
|
||||
try {
|
||||
Context.Connection.ExecuteBufferedInsert("INSERT INTO fso_lot_visit_totals (lot_id, date, minutes) VALUES (@lot_id, @date, @minutes) ON DUPLICATE KEY UPDATE minutes=VALUES(minutes)", input, 100);
|
||||
}catch(Exception ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void Purge(DateTime date)
|
||||
{
|
||||
Context.Connection.Execute("DELETE FROM fso_lot_visit_totals WHERE date < @date", new { date = date });
|
||||
}
|
||||
}
|
||||
}
|
37
server/FSO.Server.Database/DA/LotVisits/DbLotVisit.cs
Executable file
37
server/FSO.Server.Database/DA/LotVisits/DbLotVisit.cs
Executable file
|
@ -0,0 +1,37 @@
|
|||
using FSO.Common.Enum;
|
||||
using System;
|
||||
|
||||
namespace FSO.Server.Database.DA.LotVisitors
|
||||
{
|
||||
public class DbLotVisit
|
||||
{
|
||||
public int lot_visit_id { get; set; }
|
||||
public uint avatar_id { get; set; }
|
||||
public int lot_id { get; set; }
|
||||
public DbLotVisitorType type { get; set; }
|
||||
public DbLotVisitorStatus status { get; set; }
|
||||
public DateTime time_created { get; set; }
|
||||
public DateTime? time_closed { get; set; }
|
||||
}
|
||||
|
||||
public class DbLotVisitNhood : DbLotVisit
|
||||
{
|
||||
public uint neighborhood_id { get; set; }
|
||||
public uint location { get; set; }
|
||||
public LotCategory category { get; set; }
|
||||
}
|
||||
|
||||
public enum DbLotVisitorType
|
||||
{
|
||||
owner,
|
||||
roommate,
|
||||
visitor
|
||||
}
|
||||
|
||||
public enum DbLotVisitorStatus
|
||||
{
|
||||
active,
|
||||
closed,
|
||||
failed
|
||||
}
|
||||
}
|
66
server/FSO.Server.Database/DA/LotVisits/ILotVisits.cs
Executable file
66
server/FSO.Server.Database/DA/LotVisits/ILotVisits.cs
Executable file
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.LotVisitors
|
||||
{
|
||||
public interface ILotVisits
|
||||
{
|
||||
/// <summary>
|
||||
/// Records a new visit to a lot. A visit id is returned which can be used to record
|
||||
/// when the visit ends
|
||||
/// </summary>
|
||||
/// <param name="avatar_id"></param>
|
||||
/// <param name="visitor_type"></param>
|
||||
/// <param name="lot_id"></param>
|
||||
/// <returns></returns>
|
||||
int? Visit(uint avatar_id, DbLotVisitorType visitor_type, int lot_id);
|
||||
|
||||
/// <summary>
|
||||
/// Records that a visit has ended
|
||||
/// </summary>
|
||||
/// <param name="visit_id"></param>
|
||||
void Leave(int visit_id);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the timestamp on active visits. This helps detect the difference between
|
||||
/// a long visit and an error where the visit did not get closed.
|
||||
///
|
||||
/// This also lets us calculate Top 100 without downtime as we can be inclusive
|
||||
/// of active tickets
|
||||
/// </summary>
|
||||
/// <param name="visit_ids"></param>
|
||||
void Renew(IEnumerable<int> visit_ids);
|
||||
|
||||
/// <summary>
|
||||
/// Purge data older than the date given
|
||||
/// </summary>
|
||||
/// <param name="days"></param>
|
||||
void PurgeByDate(DateTime date);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<DbLotVisit> StreamBetween(int shard_id, DateTime start, DateTime end);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<DbLotVisitNhood> StreamBetweenPlusNhood(int shard_id, DateTime start, DateTime end);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<DbLotVisitNhood> StreamBetweenOneNhood(uint nhood_id, DateTime start, DateTime end);
|
||||
|
||||
|
||||
}
|
||||
}
|
50
server/FSO.Server.Database/DA/LotVisits/LotVisitUtils.cs
Executable file
50
server/FSO.Server.Database/DA/LotVisits/LotVisitUtils.cs
Executable file
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
|
||||
namespace FSO.Server.Database.DA.LotVisits
|
||||
{
|
||||
public static class LotVisitUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Calculates the overlap between two date ranges.
|
||||
/// Useful utility function for calculating visit hours.
|
||||
/// </summary>
|
||||
/// <param name="day"></param>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
public static TimeSpan CalculateDateOverlap(DateTime r1_start, DateTime r1_end, DateTime r2_start, DateTime r2_end)
|
||||
{
|
||||
var startsInRange = r2_start >= r1_start && r2_start <= r1_end;
|
||||
var endsInRange = r2_end <= r1_end && r2_end >= r1_start;
|
||||
|
||||
if (startsInRange && endsInRange)
|
||||
{
|
||||
//Within the range / equal
|
||||
return r2_end.Subtract(r2_start);
|
||||
}
|
||||
else if (startsInRange)
|
||||
{
|
||||
//Starts within range but does not end in range
|
||||
return r1_end.Subtract(r2_start);
|
||||
}
|
||||
else if (endsInRange)
|
||||
{
|
||||
//Ends in range but does not start in range
|
||||
return r2_end.Subtract(r1_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new TimeSpan(0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns midnight of the current day.
|
||||
/// Useful utility function for calculating visit hours.
|
||||
/// </summary>
|
||||
public static DateTime Midnight()
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
return new DateTime(now.Year, now.Month, now.Day, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
82
server/FSO.Server.Database/DA/LotVisits/SqlLotVisits.cs
Executable file
82
server/FSO.Server.Database/DA/LotVisits/SqlLotVisits.cs
Executable file
|
@ -0,0 +1,82 @@
|
|||
using Dapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace FSO.Server.Database.DA.LotVisitors
|
||||
{
|
||||
public class SqlLotVisits : AbstractSqlDA, ILotVisits
|
||||
{
|
||||
public SqlLotVisits(ISqlContext context) : base(context){
|
||||
}
|
||||
|
||||
public int? Visit(uint avatar_id, DbLotVisitorType visitor_type, int lot_id)
|
||||
{
|
||||
try {
|
||||
//Stored procedure will handle erroring any active visits that should no longer be active
|
||||
return Context.Connection.Query<int>("SELECT `fso_lot_visits_create`(@avatar_id, @lot_id, @type)", new {
|
||||
avatar_id = avatar_id,
|
||||
lot_id = lot_id,
|
||||
type = visitor_type.ToString()
|
||||
}).First();
|
||||
}catch(Exception ex){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Leave(int visit_id)
|
||||
{
|
||||
try
|
||||
{
|
||||
Context.Connection.Query("UPDATE `fso_lot_visits` SET status = 'closed', time_closed = current_timestamp WHERE lot_visit_id = @visit_id AND `status` = 'active'", new { visit_id = visit_id });
|
||||
}catch(Exception ex){
|
||||
}
|
||||
}
|
||||
|
||||
public void Renew(IEnumerable<int> visit_ids)
|
||||
{
|
||||
try{
|
||||
Context.Connection.Query("UPDATE `fso_lot_visits` SET time_closed = current_timestamp WHERE lot_visit_id IN @visit_ids AND `status` = 'active'", new { visit_ids = visit_ids });
|
||||
}catch (Exception ex){
|
||||
}
|
||||
}
|
||||
|
||||
public void PurgeByDate(DateTime date)
|
||||
{
|
||||
Context.Connection.Query("DELETE FROM `fso_lot_visits` WHERE time_closed IS NOT NULL AND time_closed < @date", new { date = date });
|
||||
Context.Connection.Query("DELETE FROM `fso_lot_visits` WHERE time_closed IS NULL AND time_created < @date", new { date = date });
|
||||
}
|
||||
|
||||
public IEnumerable<DbLotVisit> StreamBetween(int shard_id, DateTime start, DateTime end)
|
||||
{
|
||||
return Context.Connection.Query<DbLotVisit>(
|
||||
"SELECT * FROM `fso_lot_visits` v INNER JOIN fso_lots l ON v.lot_id = l.lot_id " +
|
||||
"WHERE l.shard_id = @shard_id AND status != 'failed' " +
|
||||
"AND time_closed IS NOT NULL " +
|
||||
"AND type = 'visitor' " +
|
||||
"AND (time_created BETWEEN @start AND @end OR time_closed BETWEEN @start and @end)",
|
||||
new { start = start, end = end, shard_id = shard_id }, buffered: false);
|
||||
}
|
||||
|
||||
public IEnumerable<DbLotVisitNhood> StreamBetweenPlusNhood(int shard_id, DateTime start, DateTime end)
|
||||
{
|
||||
return Context.Connection.Query<DbLotVisitNhood>(
|
||||
"SELECT * FROM `fso_lot_visits` v INNER JOIN fso_lots l ON v.lot_id = l.lot_id " +
|
||||
"WHERE l.shard_id = @shard_id AND status != 'failed' " +
|
||||
"AND time_closed IS NOT NULL " +
|
||||
"AND (time_created BETWEEN @start AND @end OR time_closed BETWEEN @start and @end)",
|
||||
new { start = start, end = end, shard_id = shard_id }, buffered: false);
|
||||
}
|
||||
|
||||
public IEnumerable<DbLotVisitNhood> StreamBetweenOneNhood(uint neighborhood_id, DateTime start, DateTime end)
|
||||
{
|
||||
return Context.Connection.Query<DbLotVisitNhood>(
|
||||
"SELECT * FROM `fso_lot_visits` v INNER JOIN fso_lots l ON v.lot_id = l.lot_id " +
|
||||
"WHERE l.neighborhood_id = @neighborhood_id AND status != 'failed' " +
|
||||
"AND time_closed IS NOT NULL " +
|
||||
"AND type = 'visitor' " +
|
||||
"AND (time_created BETWEEN @start AND @end OR time_closed BETWEEN @start and @end)",
|
||||
new { start = start, end = end, neighborhood_id = neighborhood_id }, buffered: false);
|
||||
}
|
||||
}
|
||||
}
|
51
server/FSO.Server.Database/DA/Lots/DbLot.cs
Executable file
51
server/FSO.Server.Database/DA/Lots/DbLot.cs
Executable file
|
@ -0,0 +1,51 @@
|
|||
using FSO.Common.Enum;
|
||||
|
||||
namespace FSO.Server.Database.DA.Lots
|
||||
{
|
||||
public class DbLot
|
||||
{
|
||||
public int lot_id { get; set; }
|
||||
public int shard_id { get; set; }
|
||||
public uint? owner_id { get; set; }
|
||||
|
||||
public string name { get; set; }
|
||||
public string description { get; set; }
|
||||
public uint location { get; set; }
|
||||
public uint neighborhood_id { get; set; }
|
||||
public uint created_date { get; set; }
|
||||
public uint category_change_date { get; set; }
|
||||
public LotCategory category { get; set; }
|
||||
public byte skill_mode { get; set; }
|
||||
public uint buildable_area { get; set; }
|
||||
public sbyte ring_backup_num { get; set; }
|
||||
public byte admit_mode { get; set; }
|
||||
public byte move_flags { get; set; }
|
||||
|
||||
public byte thumb3d_dirty { get; set; }
|
||||
public uint thumb3d_time { get; set; }
|
||||
}
|
||||
|
||||
/**Lot
|
||||
Lot_BuildableArea : Uint32 (0)
|
||||
Lot_NumOccupants : Uint8 (0)
|
||||
Lot_SpotLightText : string (0)
|
||||
Lot_Location : Location (0)
|
||||
Lot_NeighborhoodCentered : Uint32 (0)
|
||||
Lot_Thumbnail : iunknown (0)
|
||||
Lot_NeighborhoodName : string (0)
|
||||
Lot_NeighborhoodID : Uint32 (0)
|
||||
Lot_OwnerVec : Uint32 (2)
|
||||
Lot_IsOnline : bool (0)
|
||||
Lot_TerrainType : Uint32 (0)
|
||||
Lot_LeaderID : Uint32 (0)
|
||||
Lot_Name : string (0)
|
||||
Lot_DBID : Uint32 (0)
|
||||
Lot_PossibleNeighborhoodsVector : Uint32 (2)
|
||||
Lot_RoommateVec : Uint32 (2)
|
||||
Lot_LotAdmitInfo : LotAdmitInfo (0)
|
||||
Lot_Description : string (0)
|
||||
Lot_Price : Uint32 (0)
|
||||
Lot_HoursSinceLastLotCatChange : Uint32 (0)
|
||||
Lot_ThumbnailCheckSum : Uint32 (0)
|
||||
Lot_Category : Uint8 (0)**/
|
||||
}
|
15
server/FSO.Server.Database/DA/Lots/DbLotServerTicket.cs
Executable file
15
server/FSO.Server.Database/DA/Lots/DbLotServerTicket.cs
Executable file
|
@ -0,0 +1,15 @@
|
|||
namespace FSO.Server.Database.DA.Lots
|
||||
{
|
||||
public class DbLotServerTicket
|
||||
{
|
||||
public string ticket_id { get; set; }
|
||||
public uint user_id { get; set; }
|
||||
public uint date { get; set; }
|
||||
public string ip { get; set; }
|
||||
public uint avatar_id { get; set; }
|
||||
public int lot_id { get; set; }
|
||||
public int avatar_claim_id { get; set; }
|
||||
public string avatar_claim_owner { get; set; }
|
||||
public string lot_owner { get; set; }
|
||||
}
|
||||
}
|
47
server/FSO.Server.Database/DA/Lots/ILots.cs
Executable file
47
server/FSO.Server.Database/DA/Lots/ILots.cs
Executable file
|
@ -0,0 +1,47 @@
|
|||
using FSO.Common.Enum;
|
||||
using FSO.Server.Database.DA.Utils;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Lots
|
||||
{
|
||||
public interface ILots
|
||||
{
|
||||
IEnumerable<DbLot> All(int shard_id);
|
||||
PagedList<DbLot> AllByPage(int shard_id, int offset, int limit, string orderBy);
|
||||
List<uint> GetLocationsInNhood(uint nhood_id);
|
||||
List<uint> GetCommunityLocations(int shard_id);
|
||||
List<DbLot> AllLocations(int shard_id);
|
||||
DbLot GetByName(int shard_id, string name);
|
||||
DbLot GetByLocation(int shard_id, uint location);
|
||||
List<DbLot> GetAdjToLocation(int shard_id, uint location);
|
||||
DbLot GetByOwner(uint owner_id);
|
||||
DbLot Get(int id);
|
||||
List<DbLot> GetMultiple(int[] ids);
|
||||
List<DbLot> Get(IEnumerable<int> ids);
|
||||
uint Create(DbLot lot);
|
||||
bool Delete(int id);
|
||||
|
||||
void RenameLot(int id, string newName);
|
||||
void SetDirty(int id, byte dirty);
|
||||
DbLot Get3DWork();
|
||||
|
||||
List<DbLot> SearchExact(int shard_id, string name, int limit);
|
||||
List<DbLot> SearchWildcard(int shard_id, string name, int limit);
|
||||
|
||||
void UpdateRingBackup(int lot_id, sbyte ring_backup_num);
|
||||
void UpdateDescription(int lot_id, string description);
|
||||
void UpdateLotCategory(int lot_id, LotCategory category, uint skillMode);
|
||||
void UpdateLotSkillMode(int lot_id, uint skillMode);
|
||||
void UpdateLotAdmitMode(int lot_id, byte admit_mode);
|
||||
bool UpdateLocation(int lot_id, uint location, bool startFresh);
|
||||
void UpdateOwner(int lot_id, uint? avatar_id);
|
||||
void ReassignOwner(int lot_id);
|
||||
|
||||
void CreateLotServerTicket(DbLotServerTicket ticket);
|
||||
void DeleteLotServerTicket(string id);
|
||||
DbLotServerTicket GetLotServerTicket(string id);
|
||||
List<DbLotServerTicket> GetLotServerTicketsForClaimedAvatar(int claim_id);
|
||||
|
||||
int UpdateAllNeighborhoods(int shard_id);
|
||||
}
|
||||
}
|
296
server/FSO.Server.Database/DA/Lots/SqlLots.cs
Executable file
296
server/FSO.Server.Database/DA/Lots/SqlLots.cs
Executable file
|
@ -0,0 +1,296 @@
|
|||
using Dapper;
|
||||
using FSO.Common.Enum;
|
||||
using FSO.Server.Common;
|
||||
using FSO.Server.Database.DA.Roommates;
|
||||
using FSO.Server.Database.DA.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace FSO.Server.Database.DA.Lots
|
||||
{
|
||||
public class SqlLots : AbstractSqlDA, ILots
|
||||
{
|
||||
public SqlLots(ISqlContext context) : base(context){
|
||||
}
|
||||
|
||||
public DbLot Get(int id){
|
||||
return Context.Connection.Query<DbLot>("SELECT * FROM fso_lots WHERE lot_id = @id", new { id = id }).FirstOrDefault();
|
||||
}
|
||||
public List<DbLot> GetMultiple(int[] id)
|
||||
{
|
||||
String inClause = "IN (";
|
||||
for (int i = 0; i < id.Length; i++)
|
||||
{
|
||||
inClause = inClause + "'" + id.ElementAt(i) + "'" + ",";
|
||||
}
|
||||
inClause = inClause.Substring(0, inClause.Length - 1);
|
||||
inClause = inClause + ")";
|
||||
|
||||
return Context.Connection.Query<DbLot>(
|
||||
"SELECT * FROM fso_lots WHERE lot_id " + inClause
|
||||
).ToList();
|
||||
}
|
||||
|
||||
public List<DbLot> Get(IEnumerable<int> ids)
|
||||
{
|
||||
return Context.Connection.Query<DbLot>("SELECT * FROM fso_lots WHERE lot_id in @ids", new { ids = ids }).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Special. We need to create the lot and assign an owner level roommate entry immediately, so we need to use a transaction.
|
||||
/// </summary>
|
||||
/// <param name="lot"></param>
|
||||
/// <returns></returns>
|
||||
public uint Create(DbLot lot)
|
||||
{
|
||||
string failReason = "NAME";
|
||||
var t = Context.Connection.BeginTransaction();
|
||||
try
|
||||
{
|
||||
var result = (uint)Context.Connection.Query<int>("INSERT INTO fso_lots (shard_id, name, description, " +
|
||||
"owner_id, location, neighborhood_id, created_date, category_change_date, category, buildable_area) " +
|
||||
" VALUES (@shard_id, @name, @description, @owner_id, @location, " +
|
||||
" @neighborhood_id, @created_date, @category_change_date, @category, @buildable_area); SELECT LAST_INSERT_ID();", new
|
||||
{
|
||||
shard_id = lot.shard_id,
|
||||
name = lot.name,
|
||||
description = lot.description,
|
||||
owner_id = lot.owner_id,
|
||||
location = lot.location,
|
||||
neighborhood_id = lot.neighborhood_id,
|
||||
created_date = lot.created_date,
|
||||
category_change_date = lot.category_change_date,
|
||||
category = lot.category.ToString(),
|
||||
buildable_area = lot.buildable_area
|
||||
}).First();
|
||||
failReason = "NHOOD";
|
||||
UpdateNeighborhood((int)result);
|
||||
if (lot.category != LotCategory.community)
|
||||
{
|
||||
failReason = "ROOMIE";
|
||||
var roomie = new DbRoommate()
|
||||
{
|
||||
avatar_id = lot.owner_id ?? 0,
|
||||
is_pending = 0,
|
||||
lot_id = (int)result,
|
||||
permissions_level = 2
|
||||
};
|
||||
var result2 = Context.Connection.Execute("INSERT INTO fso_roommates (avatar_id, lot_id, permissions_level, is_pending) " +
|
||||
" VALUES (@avatar_id, @lot_id, @permissions_level, @is_pending);", roomie) > 0;
|
||||
if (result2)
|
||||
{
|
||||
t.Commit();
|
||||
return result;
|
||||
}
|
||||
} else
|
||||
{
|
||||
t.Commit();
|
||||
return result;
|
||||
}
|
||||
} catch (Exception)
|
||||
{
|
||||
}
|
||||
t.Rollback();
|
||||
throw new Exception(failReason);
|
||||
}
|
||||
|
||||
public bool Delete(int id)
|
||||
{
|
||||
return Context.Connection.Execute("DELETE FROM fso_lots WHERE lot_id = @id", new { id = id }) > 0;
|
||||
}
|
||||
|
||||
public DbLot GetByOwner(uint owner_id)
|
||||
{
|
||||
return Context.Connection.Query<DbLot>("SELECT * FROM fso_lots WHERE owner_id = @id AND category != 'community'", new { id = owner_id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public IEnumerable<DbLot> All(int shard_id)
|
||||
{
|
||||
return Context.Connection.Query<DbLot>("SELECT * FROM fso_lots WHERE shard_id = @shard_id", new { shard_id = shard_id });
|
||||
}
|
||||
public PagedList<DbLot> AllByPage(int shard_id, int offset = 1, int limit = 100, string orderBy = "lot_id")
|
||||
{
|
||||
var total = Context.Connection.Query<int>("SELECT COUNT(*) FROM fso_lots WHERE shard_id = @shard_id", new { shard_id = shard_id }).FirstOrDefault();
|
||||
var results = Context.Connection.Query<DbLot>("SELECT * FROM fso_lots WHERE shard_id = @shard_id ORDER BY @order DESC LIMIT @offset, @limit", new { shard_id = shard_id, order = orderBy, offset = offset, limit = limit });
|
||||
return new PagedList<DbLot>(results, offset, total);
|
||||
}
|
||||
|
||||
public List<DbLot> AllLocations(int shard_id)
|
||||
{
|
||||
return Context.Connection.Query<DbLot>("SELECT location, name FROM fso_lots WHERE shard_id = @shard_id", new { shard_id = shard_id }).ToList();
|
||||
}
|
||||
|
||||
public List<uint> GetLocationsInNhood(uint nhood_id)
|
||||
{
|
||||
return Context.Connection.Query<uint>("SELECT location FROM fso_lots WHERE neighborhood_id = @nhood_id", new { nhood_id = nhood_id }).ToList();
|
||||
}
|
||||
|
||||
public List<uint> GetCommunityLocations(int shard_id)
|
||||
{
|
||||
return Context.Connection.Query<uint>("SELECT location FROM fso_lots WHERE shard_id = @shard_id AND (category = 'community' OR category = 'recent')", new { shard_id = shard_id }).ToList();
|
||||
}
|
||||
|
||||
public List<string> AllNames(int shard_id)
|
||||
{
|
||||
return Context.Connection.Query<string>("SELECT name FROM fso_lots WHERE shard_id = @shard_id", new { shard_id = shard_id }).ToList();
|
||||
}
|
||||
|
||||
public DbLot GetByName(int shard_id, string name)
|
||||
{
|
||||
return Context.Connection.Query<DbLot>("SELECT * FROM fso_lots WHERE name = @name AND shard_id = @shard_id", new { name, shard_id = shard_id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public DbLot GetByLocation(int shard_id, uint location)
|
||||
{
|
||||
return Context.Connection.Query<DbLot>("SELECT * FROM fso_lots WHERE location = @location AND shard_id = @shard_id", new { location = location, shard_id = shard_id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public List<DbLot> GetAdjToLocation(int shard_id, uint location)
|
||||
{
|
||||
return Context.Connection.Query<DbLot>("SELECT * FROM fso_lots WHERE "
|
||||
+ "(ABS(CAST((location&65535) AS SIGNED) - CAST((@location&65535) AS SIGNED)) = 1 OR ABS(CAST((location/65536) AS SIGNED) - CAST((@location/65536) AS SIGNED)) = 1) "
|
||||
+ "AND shard_id = @shard_id AND move_flags = 0", new { location = location, shard_id = shard_id }).ToList();
|
||||
}
|
||||
|
||||
public void RenameLot(int id, string newName)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_lots SET name = @name WHERE lot_id = @id", new { name = newName, id = id });
|
||||
}
|
||||
|
||||
public void SetDirty(int id, byte dirty)
|
||||
{
|
||||
if (dirty == 0)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_lots SET thumb3d_dirty = @dirty, thumb3d_time = @time WHERE lot_id = @id", new { time = Epoch.Now, dirty = dirty, id = id });
|
||||
} else
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_lots SET thumb3d_dirty = @dirty WHERE lot_id = @id", new { dirty = dirty, id = id });
|
||||
}
|
||||
}
|
||||
|
||||
public DbLot Get3DWork()
|
||||
{
|
||||
var item = Context.Connection.Query<DbLot>("SELECT * FROM fso_lots WHERE thumb3d_dirty = 1 AND thumb3d_time < @time ORDER BY thumb3d_time LIMIT 1", new { time = Epoch.Now - 300 }).FirstOrDefault();
|
||||
if (item != null)
|
||||
{
|
||||
SetDirty(item.lot_id, 0);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public List<DbLot> SearchExact(int shard_id, string name, int limit)
|
||||
{
|
||||
return Context.Connection.Query<DbLot>(
|
||||
"SELECT lot_id, location, name FROM fso_lots WHERE shard_id = @shard_id AND name = @name LIMIT @limit",
|
||||
new { shard_id = shard_id, name = name, limit = limit }
|
||||
).ToList();
|
||||
}
|
||||
|
||||
public List<DbLot> SearchWildcard(int shard_id, string name, int limit)
|
||||
{
|
||||
name = name
|
||||
.Replace("!", "!!")
|
||||
.Replace("%", "!%")
|
||||
.Replace("_", "!_")
|
||||
.Replace("[", "!["); //must sanitize format...
|
||||
return Context.Connection.Query<DbLot>(
|
||||
"SELECT lot_id, location, name FROM fso_lots WHERE shard_id = @shard_id AND name LIKE @name LIMIT @limit",
|
||||
new { shard_id = shard_id, name = "%" + name + "%", limit = limit }
|
||||
).ToList();
|
||||
}
|
||||
|
||||
public void UpdateRingBackup(int lot_id, sbyte ring_backup_num)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_lots SET ring_backup_num = @ring_backup_num, move_flags = 0 WHERE lot_id = @id",
|
||||
new { ring_backup_num = ring_backup_num, id = lot_id });
|
||||
}
|
||||
|
||||
|
||||
public void CreateLotServerTicket(DbLotServerTicket ticket)
|
||||
{
|
||||
Context.Connection.Execute("INSERT INTO fso_lot_server_tickets VALUES (@ticket_id, @user_id, @date, @ip, @avatar_id, @lot_id, @avatar_claim_id, @avatar_claim_owner, @lot_owner)", ticket);
|
||||
}
|
||||
|
||||
public void DeleteLotServerTicket(string id)
|
||||
{
|
||||
Context.Connection.Execute("DELETE FROM fso_lot_server_tickets WHERE ticket_id = @ticket_id", new { ticket_id = id });
|
||||
}
|
||||
|
||||
public DbLotServerTicket GetLotServerTicket(string id)
|
||||
{
|
||||
return Context.Connection.Query<DbLotServerTicket>("SELECT * FROM fso_lot_server_tickets WHERE ticket_id = @ticket_id", new { ticket_id = id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public List<DbLotServerTicket> GetLotServerTicketsForClaimedAvatar(int claim_id)
|
||||
{
|
||||
return Context.Connection.Query<DbLotServerTicket>("SELECT * FROM fso_lot_server_tickets WHERE avatar_claim_id = @claim_id", new { claim_id = claim_id }).ToList();
|
||||
}
|
||||
|
||||
public void UpdateDescription(int lot_id, string description)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_lots SET description = @desc WHERE lot_id = @id", new { id = lot_id, desc = description });
|
||||
}
|
||||
|
||||
public void UpdateOwner(int lot_id, uint? avatar_id)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_lots SET owner_id = @owner_id WHERE lot_id = @id", new { id = lot_id, owner_id = avatar_id });
|
||||
}
|
||||
|
||||
public void ReassignOwner(int lot_id)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_lots SET owner_id = (SELECT avatar_id FROM fso_roommates WHERE is_pending = 0 AND lot_id = @id LIMIT 1) WHERE lot_id = @id", new { id = lot_id });
|
||||
Context.Connection.Query("UPDATE fso_roommates SET permissions_level = 2 WHERE avatar_id = (SELECT owner_id FROM fso_lots WHERE lot_id = @id LIMIT 1) AND lot_id = @id", new { id = lot_id });
|
||||
}
|
||||
|
||||
public void UpdateLotSkillMode(int lot_id, uint skillMode)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_lots SET skill_mode = @skillMode WHERE lot_id = @id",
|
||||
new { id = lot_id, skillMode = skillMode });
|
||||
}
|
||||
|
||||
public void UpdateLotCategory(int lot_id, LotCategory category, uint skillMode)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_lots SET category = @category, category_change_date = @time, skill_mode = @skillMode WHERE lot_id = @id",
|
||||
new { id = lot_id, category = category.ToString(), time = Epoch.Now, skillMode = skillMode });
|
||||
}
|
||||
|
||||
public void UpdateLotAdmitMode(int lot_id, byte admit_mode)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_lots SET admit_mode = @admit_mode WHERE lot_id = @id", new { id = lot_id, admit_mode = admit_mode });
|
||||
}
|
||||
|
||||
public bool UpdateLocation(int lot_id, uint location, bool startFresh)
|
||||
{
|
||||
var success = Context.Connection.Execute("UPDATE fso_lots SET location = @location, move_flags = @move WHERE lot_id = @id", new { id = lot_id, location = location, move = (byte)(startFresh?2:1) }) > 0;
|
||||
if (success)
|
||||
UpdateNeighborhood(lot_id);
|
||||
return success;
|
||||
}
|
||||
|
||||
private static string NHoodQuery =
|
||||
"UPDATE fso.fso_lots l " +
|
||||
"SET neighborhood_id = " +
|
||||
"COALESCE((SELECT neighborhood_id " +
|
||||
"FROM fso.fso_neighborhoods n " +
|
||||
"ORDER BY(POWER(((l.location & 65535) + 0.0) - ((n.location & 65535) + 0.0), 2) + " +
|
||||
"POWER((FLOOR(l.location / 65536) + 0.0) - (FLOOR(n.location / 65536) + 0.0), 2)) " +
|
||||
"LIMIT 1), 0) ";
|
||||
|
||||
public int UpdateAllNeighborhoods(int shard_id)
|
||||
{
|
||||
return Context.Connection.Execute(
|
||||
NHoodQuery +
|
||||
"WHERE l.shard_id = @shard_id"
|
||||
, new { shard_id = shard_id });
|
||||
}
|
||||
|
||||
public bool UpdateNeighborhood(int lot_id)
|
||||
{
|
||||
return (Context.Connection.Execute(
|
||||
NHoodQuery +
|
||||
"WHERE l.lot_id = @lot_id"
|
||||
, new { lot_id = lot_id })) > 0;
|
||||
}
|
||||
}
|
||||
}
|
46
server/FSO.Server.Database/DA/MySqlContext.cs
Executable file
46
server/FSO.Server.Database/DA/MySqlContext.cs
Executable file
|
@ -0,0 +1,46 @@
|
|||
using MySql.Data.MySqlClient;
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
|
||||
namespace FSO.Server.Database.DA
|
||||
{
|
||||
public class MySqlContext : ISqlContext, IDisposable
|
||||
{
|
||||
private readonly string _connectionString;
|
||||
private DbConnection _connection;
|
||||
|
||||
public MySqlContext(string connectionString)
|
||||
{
|
||||
this._connectionString = connectionString;
|
||||
}
|
||||
|
||||
public DbConnection Connection
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_connection == null)
|
||||
_connection = new MySqlConnection(_connectionString);
|
||||
|
||||
if (_connection.State != ConnectionState.Open)
|
||||
_connection.Open();
|
||||
|
||||
return _connection;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_connection != null)
|
||||
{
|
||||
_connection.Dispose();
|
||||
_connection = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Flush()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
}
|
17
server/FSO.Server.Database/DA/MySqlDAFactory.cs
Executable file
17
server/FSO.Server.Database/DA/MySqlDAFactory.cs
Executable file
|
@ -0,0 +1,17 @@
|
|||
namespace FSO.Server.Database.DA
|
||||
{
|
||||
public class MySqlDAFactory : IDAFactory
|
||||
{
|
||||
private DatabaseConfiguration Config;
|
||||
|
||||
public MySqlDAFactory(DatabaseConfiguration config)
|
||||
{
|
||||
this.Config = config;
|
||||
}
|
||||
|
||||
public IDA Get()
|
||||
{
|
||||
return new SqlDA(new MySqlContext(Config.ConnectionString));
|
||||
}
|
||||
}
|
||||
}
|
22
server/FSO.Server.Database/DA/Neighborhoods/DbNeighborhood.cs
Executable file
22
server/FSO.Server.Database/DA/Neighborhoods/DbNeighborhood.cs
Executable file
|
@ -0,0 +1,22 @@
|
|||
namespace FSO.Server.Database.DA.Neighborhoods
|
||||
{
|
||||
public class DbNeighborhood
|
||||
{
|
||||
public int neighborhood_id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string description { get; set; }
|
||||
public int shard_id { get; set; }
|
||||
|
||||
public uint location { get; set; }
|
||||
public uint color { get; set; }
|
||||
public uint flag { get; set; }
|
||||
|
||||
public int? town_hall_id { get; set; }
|
||||
public string icon_url { get; set; }
|
||||
public string guid { get; set; }
|
||||
|
||||
public uint? mayor_id { get; set; }
|
||||
public uint mayor_elected_date { get; set; }
|
||||
public uint? election_cycle_id { get; set; }
|
||||
}
|
||||
}
|
9
server/FSO.Server.Database/DA/Neighborhoods/DbNhoodBan.cs
Executable file
9
server/FSO.Server.Database/DA/Neighborhoods/DbNhoodBan.cs
Executable file
|
@ -0,0 +1,9 @@
|
|||
namespace FSO.Server.Database.DA.Neighborhoods
|
||||
{
|
||||
public class DbNhoodBan
|
||||
{
|
||||
public uint user_id { get; set; }
|
||||
public string ban_reason { get; set; }
|
||||
public uint end_date { get; set; }
|
||||
}
|
||||
}
|
27
server/FSO.Server.Database/DA/Neighborhoods/INeighborhoods.cs
Executable file
27
server/FSO.Server.Database/DA/Neighborhoods/INeighborhoods.cs
Executable file
|
@ -0,0 +1,27 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Neighborhoods
|
||||
{
|
||||
public interface INeighborhoods
|
||||
{
|
||||
List<DbNeighborhood> All(int shard_id);
|
||||
DbNeighborhood Get(uint neighborhood_id);
|
||||
DbNeighborhood GetByMayor(uint mayor_id);
|
||||
DbNeighborhood GetByLocation(uint location);
|
||||
int DeleteMissing(int shard_id, List<string> AllGUIDs);
|
||||
int UpdateFromJSON(DbNeighborhood update);
|
||||
int AddNhood(DbNeighborhood update);
|
||||
void UpdateDescription(uint neighborhood_id, string description);
|
||||
void UpdateMayor(uint neigh_id, uint? mayor_id);
|
||||
void UpdateTownHall(uint neigh_id, uint? lot_id);
|
||||
void UpdateCycle(uint neigh_id, uint? cycle_id);
|
||||
void UpdateName(uint neighborhood_id, string name);
|
||||
void UpdateFlag(uint neighborhood_id, uint flag);
|
||||
|
||||
DbNhoodBan GetNhoodBan(uint user_id);
|
||||
bool AddNhoodBan(DbNhoodBan ban);
|
||||
|
||||
List<DbNeighborhood> SearchExact(int shard_id, string name, int limit);
|
||||
List<DbNeighborhood> SearchWildcard(int shard_id, string name, int limit);
|
||||
}
|
||||
}
|
150
server/FSO.Server.Database/DA/Neighborhoods/SqlNeighborhoods.cs
Executable file
150
server/FSO.Server.Database/DA/Neighborhoods/SqlNeighborhoods.cs
Executable file
|
@ -0,0 +1,150 @@
|
|||
using Dapper;
|
||||
using FSO.Server.Common;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FSO.Server.Database.DA.Neighborhoods
|
||||
{
|
||||
public class SqlNeighborhoods : AbstractSqlDA, INeighborhoods
|
||||
{
|
||||
public SqlNeighborhoods(ISqlContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public int AddNhood(DbNeighborhood hood)
|
||||
{
|
||||
var result = Context.Connection.Query<int>("INSERT INTO fso_neighborhoods (name, description, " +
|
||||
"shard_id, location, color, guid) " +
|
||||
" VALUES (@name, @description, " +
|
||||
" @shard_id, @location, @color, @guid); SELECT LAST_INSERT_ID();", hood).First();
|
||||
return result;
|
||||
}
|
||||
|
||||
public int DeleteMissing(int shard_id, List<string> AllGUIDs)
|
||||
{
|
||||
var sCommand = new StringBuilder();
|
||||
bool first = true;
|
||||
foreach (var item in AllGUIDs)
|
||||
{
|
||||
if (first) sCommand.Append("(");
|
||||
else sCommand.Append(",");
|
||||
sCommand.Append("'"+item+"'");
|
||||
first = false;
|
||||
}
|
||||
sCommand.Append(")");
|
||||
|
||||
var deleted = Context.Connection.Execute("DELETE FROM fso_neighborhoods WHERE shard_id = @shard_id AND guid NOT IN "
|
||||
+ sCommand.ToString(), new { shard_id = shard_id });
|
||||
|
||||
return deleted;
|
||||
}
|
||||
|
||||
public List<DbNeighborhood> All(int shard_id)
|
||||
{
|
||||
return Context.Connection.Query<DbNeighborhood>("SELECT * FROM fso_neighborhoods WHERE shard_id = @shard_id",
|
||||
new { shard_id = shard_id }).ToList();
|
||||
}
|
||||
|
||||
public DbNeighborhood Get(uint neighborhood_id)
|
||||
{
|
||||
return Context.Connection.Query<DbNeighborhood>("SELECT * FROM fso_neighborhoods WHERE neighborhood_id = @neighborhood_id",
|
||||
new { neighborhood_id = neighborhood_id}).FirstOrDefault();
|
||||
}
|
||||
|
||||
public DbNeighborhood GetByMayor(uint avatar_id)
|
||||
{
|
||||
return Context.Connection.Query<DbNeighborhood>("SELECT * FROM fso_neighborhoods WHERE mayor_id = @avatar_id",
|
||||
new { avatar_id = avatar_id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public DbNeighborhood GetByLocation(uint location)
|
||||
{
|
||||
return Context.Connection.Query<DbNeighborhood>(
|
||||
"SELECT neighborhood_id " +
|
||||
"FROM fso.fso_neighborhoods n " +
|
||||
"ORDER BY(POWER(((@location & 65535) + 0.0) - ((n.location & 65535) + 0.0), 2) + " +
|
||||
"POWER((FLOOR(@location / 65536) + 0.0) - (FLOOR(n.location / 65536) + 0.0), 2)) " +
|
||||
"LIMIT 1", new { location = location }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public int UpdateFromJSON(DbNeighborhood update)
|
||||
{
|
||||
if (update.description != null)
|
||||
return Context.Connection.Execute("UPDATE fso_neighborhoods SET name = @name, description = @description, "
|
||||
+ "location = @location, color = @color WHERE guid = @guid AND shard_id = @shard_id", update);
|
||||
else
|
||||
return Context.Connection.Execute("UPDATE fso_neighborhoods SET name = @name, location = @location, "
|
||||
+ "color = @color WHERE guid = @guid AND shard_id = @shard_id", update);
|
||||
}
|
||||
|
||||
public void UpdateDescription(uint neigh_id, string description)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_neighborhoods SET description = @desc WHERE neighborhood_id = @id", new { id = neigh_id, desc = description });
|
||||
}
|
||||
|
||||
public void UpdateMayor(uint neigh_id, uint? mayor_id)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_neighborhoods SET mayor_id = @mayor_id, mayor_elected_date = @date WHERE neighborhood_id = @id",
|
||||
new { id = neigh_id, mayor_id = mayor_id, date = Epoch.Now });
|
||||
}
|
||||
|
||||
public void UpdateTownHall(uint neigh_id, uint? lot_id)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_neighborhoods SET town_hall_id = @lot_id WHERE neighborhood_id = @id", new { id = neigh_id, lot_id = lot_id });
|
||||
}
|
||||
|
||||
public void UpdateCycle(uint neigh_id, uint? cycle_id)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_neighborhoods SET election_cycle_id = @cycle_id WHERE neighborhood_id = @id", new { id = neigh_id, cycle_id = cycle_id });
|
||||
}
|
||||
|
||||
public void UpdateName(uint neigh_id, string name)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_neighborhoods SET name = @name WHERE neighborhood_id = @id", new { id = neigh_id, name = name });
|
||||
}
|
||||
|
||||
public void UpdateFlag(uint neigh_id, uint flag)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_neighborhoods SET flag = @flag WHERE neighborhood_id = @id", new { id = neigh_id, flag = flag });
|
||||
}
|
||||
|
||||
public DbNhoodBan GetNhoodBan(uint user_id)
|
||||
{
|
||||
var date = Epoch.Now;
|
||||
return Context.Connection.Query<DbNhoodBan>("SELECT * FROM fso_nhood_ban WHERE user_id = @user_id AND end_date > @date",
|
||||
new { user_id = user_id, date = date }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public bool AddNhoodBan(DbNhoodBan ban)
|
||||
{
|
||||
var result = Context.Connection.Query<int>("INSERT INTO fso_nhood_ban (user_id, ban_reason, end_date) " +
|
||||
"VALUES (@user_id, @ban_reason, @end_date) " +
|
||||
"ON DUPLICATE KEY UPDATE ban_reason = @ban_reason, end_date = @end_date; " +
|
||||
"SELECT LAST_INSERT_ID();", ban).First();
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
public List<DbNeighborhood> SearchExact(int shard_id, string name, int limit)
|
||||
{
|
||||
return Context.Connection.Query<DbNeighborhood>(
|
||||
"SELECT neighborhood_id, location, name FROM fso_neighborhoods WHERE shard_id = @shard_id AND name = @name LIMIT @limit",
|
||||
new { shard_id = shard_id, name = name, limit = limit }
|
||||
).ToList();
|
||||
}
|
||||
|
||||
public List<DbNeighborhood> SearchWildcard(int shard_id, string name, int limit)
|
||||
{
|
||||
name = name
|
||||
.Replace("!", "!!")
|
||||
.Replace("%", "!%")
|
||||
.Replace("_", "!_")
|
||||
.Replace("[", "!["); //must sanitize format...
|
||||
return Context.Connection.Query<DbNeighborhood>(
|
||||
"SELECT neighborhood_id, location, name FROM fso_neighborhoods WHERE shard_id = @shard_id AND name LIKE @name LIMIT @limit",
|
||||
new { shard_id = shard_id, name = "%" + name + "%", limit = limit }
|
||||
).ToList();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
32
server/FSO.Server.Database/DA/Objects/DbObject.cs
Executable file
32
server/FSO.Server.Database/DA/Objects/DbObject.cs
Executable file
|
@ -0,0 +1,32 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Objects
|
||||
{
|
||||
public class DbObject
|
||||
{
|
||||
//general persist idenfification
|
||||
public uint object_id { get; set; }
|
||||
public int shard_id { get; set; }
|
||||
public uint? owner_id { get; set; }
|
||||
public int? lot_id { get; set; }
|
||||
|
||||
//object info. most of this is unused, but can be used to show state for inventory objects
|
||||
public string dyn_obj_name { get; set; }
|
||||
public uint type { get; set; } //guid
|
||||
public ushort graphic { get; set; }
|
||||
public uint value { get; set; }
|
||||
public int budget { get; set; }
|
||||
public ulong dyn_flags_1 { get; set; }
|
||||
public ulong dyn_flags_2 { get; set; }
|
||||
|
||||
//upgrades
|
||||
public uint upgrade_level { get; set; }
|
||||
|
||||
//token system
|
||||
//if >0, attributes are stored on db rather than in state.
|
||||
//if 2, we're a value token. (attr 0 contains number that should be displayed in UI)
|
||||
public byte has_db_attributes { get; set; }
|
||||
|
||||
public List<int> AugmentedAttributes;
|
||||
}
|
||||
}
|
9
server/FSO.Server.Database/DA/Objects/DbObjectAttribute.cs
Executable file
9
server/FSO.Server.Database/DA/Objects/DbObjectAttribute.cs
Executable file
|
@ -0,0 +1,9 @@
|
|||
namespace FSO.Server.Database.DA.Objects
|
||||
{
|
||||
public class DbObjectAttribute
|
||||
{
|
||||
public uint object_id { get; set; }
|
||||
public int index { get; set; }
|
||||
public int value { get; set; }
|
||||
}
|
||||
}
|
33
server/FSO.Server.Database/DA/Objects/IObjects.cs
Executable file
33
server/FSO.Server.Database/DA/Objects/IObjects.cs
Executable file
|
@ -0,0 +1,33 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Objects
|
||||
{
|
||||
public interface IObjects
|
||||
{
|
||||
uint Create(DbObject obj);
|
||||
|
||||
DbObject Get(uint id);
|
||||
bool Delete(uint id);
|
||||
IEnumerable<DbObject> All(int shard_id);
|
||||
List<DbObject> GetAvatarInventory(uint avatar_id);
|
||||
List<DbObject> GetAvatarInventoryWithAttrs(uint avatar_id);
|
||||
List<DbObject> ObjOfTypeForAvatar(uint avatar_id, uint guid);
|
||||
List<DbObject> ObjOfTypeInAvatarInventory(uint avatar_id, uint guid);
|
||||
List<DbObject> GetObjectOwners(IEnumerable<uint> object_ids);
|
||||
int ReturnLostObjects(uint lot_id, IEnumerable<uint> object_ids);
|
||||
bool ConsumeObjsOfTypeInAvatarInventory(uint avatar_id, uint guid, int num);
|
||||
List<DbObject> GetByAvatarId(uint avatar_id);
|
||||
List<DbObject> GetByAvatarIdLot(uint avatar_id, uint lot_id);
|
||||
int UpdateObjectOwnerLot(uint avatar_id, int lot_id, uint targ_avatar_id, List<uint> untradableGUIDs);
|
||||
|
||||
bool UpdatePersistState(uint id, DbObject obj);
|
||||
bool SetInLot(uint id, uint? lot_id);
|
||||
|
||||
int ChangeInventoryOwners(IEnumerable<uint> object_ids, uint oldOwner, uint newOwner);
|
||||
|
||||
List<DbObjectAttribute> GetObjectAttributes(List<uint> objects);
|
||||
int GetSpecificObjectAttribute(uint objectID, int index);
|
||||
void SetObjectAttributes(List<DbObjectAttribute> attrs);
|
||||
int TotalObjectAttributes(uint guid, int index);
|
||||
}
|
||||
}
|
225
server/FSO.Server.Database/DA/Objects/SqlObjects.cs
Executable file
225
server/FSO.Server.Database/DA/Objects/SqlObjects.cs
Executable file
|
@ -0,0 +1,225 @@
|
|||
using Dapper;
|
||||
using FSO.Server.Database.DA.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FSO.Server.Database.DA.Objects
|
||||
{
|
||||
public class SqlObjects : AbstractSqlDA, IObjects
|
||||
{
|
||||
public SqlObjects(ISqlContext context) : base(context){
|
||||
}
|
||||
|
||||
public IEnumerable<DbObject> All(int shard_id)
|
||||
{
|
||||
return Context.Connection.Query<DbObject>("SELECT * FROM fso_objects WHERE shard_id = @shard_id", new { shard_id = shard_id });
|
||||
}
|
||||
|
||||
public uint Create(DbObject obj)
|
||||
{
|
||||
return (uint)Context.Connection.Query<int>("INSERT INTO fso_objects (shard_id, owner_id, lot_id, " +
|
||||
"dyn_obj_name, type, graphic, value, budget, upgrade_level, has_db_attributes) " +
|
||||
" VALUES (@shard_id, @owner_id, @lot_id, @dyn_obj_name, @type," +
|
||||
" @graphic, @value, @budget, @upgrade_level, @has_db_attributes); SELECT LAST_INSERT_ID();"
|
||||
, obj).First();
|
||||
}
|
||||
|
||||
public DbObject Get(uint id)
|
||||
{
|
||||
return Context.Connection.Query<DbObject>("SELECT * FROM fso_objects WHERE object_id = @object_id", new { object_id = id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public bool Delete(uint id)
|
||||
{
|
||||
return Context.Connection.Execute("DELETE FROM fso_objects WHERE object_id = @object_id", new { object_id = id }) > 0;
|
||||
}
|
||||
|
||||
public List<DbObject> GetAvatarInventory(uint avatar_id)
|
||||
{
|
||||
return Context.Connection.Query<DbObject>("SELECT * FROM fso_objects WHERE owner_id = @avatar_id AND lot_id IS NULL", new { avatar_id = avatar_id }).ToList();
|
||||
}
|
||||
|
||||
public List<DbObject> GetAvatarInventoryWithAttrs(uint avatar_id)
|
||||
{
|
||||
var inventory = GetAvatarInventory(avatar_id);
|
||||
var toLoad = inventory.Where(x => x.has_db_attributes > 0);
|
||||
if (toLoad.Count() == 0) return inventory;
|
||||
var attrs = GetObjectAttributes(toLoad.Select(x => x.object_id).ToList());
|
||||
foreach (var attr in attrs)
|
||||
{
|
||||
var target = toLoad.FirstOrDefault(x => x.object_id == attr.object_id);
|
||||
if (target == null) continue;
|
||||
if (target.AugmentedAttributes == null) target.AugmentedAttributes = new List<int>();
|
||||
var targList = target.AugmentedAttributes;
|
||||
while (targList.Count <= attr.index) targList.Add(0);
|
||||
targList[attr.index] = attr.value;
|
||||
}
|
||||
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public List<DbObject> ObjOfTypeForAvatar(uint avatar_id, uint guid)
|
||||
{
|
||||
return Context.Connection.Query<DbObject>("SELECT * FROM fso_objects WHERE owner_id = @avatar_id AND type = @guid",
|
||||
new { avatar_id = avatar_id, guid = guid }).ToList();
|
||||
}
|
||||
|
||||
public List<DbObject> ObjOfTypeInAvatarInventory(uint avatar_id, uint guid)
|
||||
{
|
||||
return Context.Connection.Query<DbObject>("SELECT * FROM fso_objects WHERE owner_id = @avatar_id AND lot_id IS NULL AND type = @guid",
|
||||
new { avatar_id = avatar_id, guid = guid}).ToList();
|
||||
}
|
||||
|
||||
public int ReturnLostObjects(uint lot_id, IEnumerable<uint> object_ids)
|
||||
{
|
||||
var sCommand = new StringBuilder();
|
||||
bool first = true;
|
||||
foreach (var item in object_ids)
|
||||
{
|
||||
if (first) sCommand.Append("(");
|
||||
else sCommand.Append(",");
|
||||
sCommand.Append(item);
|
||||
first = false;
|
||||
}
|
||||
sCommand.Append(")");
|
||||
|
||||
return Context.Connection.Execute("UPDATE fso_objects SET lot_id = NULL WHERE lot_id = @lot_id AND object_id NOT IN " + sCommand.ToString(), new { lot_id = lot_id });
|
||||
}
|
||||
|
||||
public List<DbObject> GetObjectOwners(IEnumerable<uint> object_ids)
|
||||
{
|
||||
if (object_ids.Count() == 0) return new List<DbObject>();
|
||||
var sCommand = new StringBuilder();
|
||||
bool first = true;
|
||||
foreach (var item in object_ids)
|
||||
{
|
||||
if (first) sCommand.Append("(");
|
||||
else sCommand.Append(",");
|
||||
sCommand.Append(item);
|
||||
first = false;
|
||||
}
|
||||
sCommand.Append(")");
|
||||
|
||||
return Context.Connection.Query<DbObject>("SELECT object_id, lot_id, owner_id FROM fso_objects WHERE object_id IN " + sCommand.ToString()).ToList();
|
||||
}
|
||||
|
||||
public bool ConsumeObjsOfTypeInAvatarInventory(uint avatar_id, uint guid, int num)
|
||||
{
|
||||
var objs = ObjOfTypeInAvatarInventory(avatar_id, guid);
|
||||
if (objs.Count < num) return false;
|
||||
//perform transaction to remove correct number of items from inventory.
|
||||
var t = Context.Connection.BeginTransaction();
|
||||
try
|
||||
{
|
||||
var sel = new List<DbObject>();
|
||||
for (int i = 0; i < num; i++) sel.Add(objs[i]);
|
||||
var sCommand = new StringBuilder();
|
||||
bool first = true;
|
||||
foreach (var item in sel)
|
||||
{
|
||||
if (first) sCommand.Append("(");
|
||||
else sCommand.Append(",");
|
||||
sCommand.Append(item.object_id);
|
||||
first = false;
|
||||
}
|
||||
sCommand.Append(");");
|
||||
var deleted = Context.Connection.Execute("DELETE FROM fso_objects WHERE object_id IN "+sCommand.ToString());
|
||||
if (deleted != num) throw new Exception("Inventory modified while attempting to delete objects!");
|
||||
} catch (Exception)
|
||||
{
|
||||
t.Rollback();
|
||||
return false;
|
||||
}
|
||||
t.Commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<DbObject> GetByAvatarId(uint avatar_id)
|
||||
{
|
||||
return Context.Connection.Query<DbObject>("SELECT * FROM fso_objects WHERE owner_id = @avatar_id", new { avatar_id = avatar_id }).ToList();
|
||||
}
|
||||
|
||||
public List<DbObject> GetByAvatarIdLot(uint avatar_id, uint lot_id)
|
||||
{
|
||||
return Context.Connection.Query<DbObject>("SELECT * FROM fso_objects WHERE owner_id = @avatar_id AND lot_id = @lot_id", new { avatar_id = avatar_id, lot_id = lot_id }).ToList();
|
||||
}
|
||||
|
||||
public int UpdateObjectOwnerLot(uint avatar_id, int lot_id, uint targ_avatar_id, List<uint> untradableGUIDs)
|
||||
{
|
||||
var sCommand = new StringBuilder();
|
||||
bool first = true;
|
||||
foreach (var item in untradableGUIDs)
|
||||
{
|
||||
if (first) sCommand.Append("(");
|
||||
else sCommand.Append(",");
|
||||
sCommand.Append(item);
|
||||
first = false;
|
||||
}
|
||||
sCommand.Append(")");
|
||||
|
||||
return Context.Connection.Execute("UPDATE fso_objects SET owner_id = @targ_avatar_id WHERE lot_id = @lot_id AND owner_id = @avatar_id AND type NOT IN " + sCommand.ToString(),
|
||||
new { avatar_id = avatar_id, lot_id = lot_id, targ_avatar_id = targ_avatar_id });
|
||||
}
|
||||
|
||||
public bool SetInLot(uint id, uint? lot_id)
|
||||
{
|
||||
return Context.Connection.Execute("UPDATE fso_objects SET lot_id = @lot_id WHERE object_id = @object_id AND ((@lot_id IS NULL) OR (lot_id IS NULL))", new { lot_id = lot_id, object_id = id }) > 0;
|
||||
}
|
||||
|
||||
public bool UpdatePersistState(uint id, DbObject obj)
|
||||
{
|
||||
return Context.Connection.Execute("UPDATE fso_objects "
|
||||
+"SET lot_id = @lot_id, "
|
||||
+ "owner_id = @owner_id, "
|
||||
+ "dyn_obj_name = @dyn_obj_name, "
|
||||
+ "graphic = @graphic, "
|
||||
+ "value = @value, "
|
||||
+ "dyn_flags_1 = @dyn_flags_1, "
|
||||
+ "dyn_flags_2 = @dyn_flags_2, "
|
||||
+ "upgrade_level = @upgrade_level, "
|
||||
+ "has_db_attributes = @has_db_attributes "
|
||||
+ "WHERE object_id = @object_id AND (@lot_id IS NULL OR lot_id = @lot_id);", obj) > 0;
|
||||
}
|
||||
|
||||
public int ChangeInventoryOwners(IEnumerable<uint> object_ids, uint oldOwner, uint newOwner)
|
||||
{
|
||||
if (object_ids.Count() == 0) return 0;
|
||||
var sCommand = new StringBuilder();
|
||||
bool first = true;
|
||||
foreach (var item in object_ids)
|
||||
{
|
||||
if (first) sCommand.Append("(");
|
||||
else sCommand.Append(",");
|
||||
sCommand.Append(item);
|
||||
first = false;
|
||||
}
|
||||
sCommand.Append(")");
|
||||
|
||||
return Context.Connection.Execute("UPDATE fso_objects SET owner_id = @newOwner WHERE owner_id = @oldOwner AND object_id IN " + sCommand.ToString(), new { oldOwner = oldOwner, newOwner = newOwner });
|
||||
}
|
||||
|
||||
public List<DbObjectAttribute> GetObjectAttributes(List<uint> objects)
|
||||
{
|
||||
return Context.Connection.Query<DbObjectAttribute>("SELECT * FROM fso_object_attributes WHERE object_id in @ids", new { ids = objects }).ToList();
|
||||
}
|
||||
|
||||
public int GetSpecificObjectAttribute(uint objectID, int index)
|
||||
{
|
||||
return Context.Connection.Query<int>("SELECT value FROM fso_object_attributes WHERE object_id = @object_id AND `index` = @index", new { object_id = objectID, index }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public void SetObjectAttributes(List<DbObjectAttribute> attrs)
|
||||
{
|
||||
Context.Connection.ExecuteBufferedInsert("INSERT INTO fso_object_attributes (object_id, `index`, value) VALUES (@object_id, @index, @value) ON DUPLICATE KEY UPDATE value = @value", attrs, 100);
|
||||
}
|
||||
|
||||
public int TotalObjectAttributes(uint guid, int index)
|
||||
{
|
||||
return Context.Connection.Query<int>("SELECT SUM(a.value) " +
|
||||
"FROM fso_object_attributes a JOIN fso_objects o ON a.object_id = o.object_id " +
|
||||
"WHERE `type` = @guid AND `index` = @index", new { guid, index }).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
22
server/FSO.Server.Database/DA/Outfits/DbOutfit.cs
Executable file
22
server/FSO.Server.Database/DA/Outfits/DbOutfit.cs
Executable file
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
|
||||
namespace FSO.Server.Database.DA.Outfits
|
||||
{
|
||||
public class DbOutfit
|
||||
{
|
||||
public uint outfit_id { get; set; }
|
||||
public Nullable<uint> avatar_owner { get; set; }
|
||||
public Nullable<uint> object_owner { get; set; }
|
||||
public ulong asset_id { get; set; }
|
||||
public int sale_price { get; set; }
|
||||
public int purchase_price { get; set; }
|
||||
public byte outfit_type { get; set; }
|
||||
public DbOutfitSource outfit_source { get; set; }
|
||||
}
|
||||
|
||||
public enum DbOutfitSource
|
||||
{
|
||||
cas,
|
||||
rack
|
||||
}
|
||||
}
|
16
server/FSO.Server.Database/DA/Outfits/IOutfits.cs
Executable file
16
server/FSO.Server.Database/DA/Outfits/IOutfits.cs
Executable file
|
@ -0,0 +1,16 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Outfits
|
||||
{
|
||||
public interface IOutfits
|
||||
{
|
||||
uint Create(DbOutfit outfit);
|
||||
List<DbOutfit> GetByObjectId(uint object_id);
|
||||
List<DbOutfit> GetByAvatarId(uint avatar_id);
|
||||
|
||||
bool UpdatePrice(uint outfit_id, uint object_id, int new_price);
|
||||
bool ChangeOwner(uint outfit_id, uint object_owner, uint new_avatar_owner);
|
||||
bool DeleteFromObject(uint outfit_id, uint object_id);
|
||||
bool DeleteFromAvatar(uint outfit_id, uint avatar_id);
|
||||
}
|
||||
}
|
64
server/FSO.Server.Database/DA/Outfits/SqlOutfits.cs
Executable file
64
server/FSO.Server.Database/DA/Outfits/SqlOutfits.cs
Executable file
|
@ -0,0 +1,64 @@
|
|||
using Dapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace FSO.Server.Database.DA.Outfits
|
||||
{
|
||||
public class SqlOutfits : AbstractSqlDA, IOutfits
|
||||
{
|
||||
public SqlOutfits(ISqlContext context) : base(context){
|
||||
}
|
||||
|
||||
public uint Create(DbOutfit outfit)
|
||||
{
|
||||
try {
|
||||
return (uint)Context.Connection.Query<int>("INSERT INTO fso_outfits (avatar_owner, object_owner, asset_id, sale_price, purchase_price, outfit_type, outfit_source) " +
|
||||
" VALUES (@avatar_owner, @object_owner, @asset_id, @sale_price, @purchase_price, @outfit_type, @outfit_source); " +
|
||||
" SELECT LAST_INSERT_ID();"
|
||||
, new {
|
||||
avatar_owner = outfit.avatar_owner,
|
||||
object_owner = outfit.object_owner,
|
||||
asset_id = outfit.asset_id,
|
||||
sale_price = outfit.sale_price,
|
||||
purchase_price = outfit.purchase_price,
|
||||
outfit_type = outfit.outfit_type,
|
||||
outfit_source = outfit.outfit_source.ToString()
|
||||
}).First();
|
||||
}catch(Exception ex){
|
||||
return uint.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ChangeOwner(uint outfit_id, uint object_owner, uint new_avatar_owner)
|
||||
{
|
||||
return Context.Connection.Execute("UPDATE fso_outfits SET avatar_owner = @avatar_owner, object_owner = NULL WHERE outfit_id = @outfit_id and object_owner = @object_owner", new { outfit_id = outfit_id, object_owner = object_owner, avatar_owner = new_avatar_owner }) > 0;
|
||||
}
|
||||
|
||||
public bool UpdatePrice(uint outfit_id, uint object_owner, int new_price)
|
||||
{
|
||||
return Context.Connection.Execute("UPDATE fso_outfits SET sale_price = @sale_price WHERE outfit_id = @outfit_id AND object_owner = @object_owner", new { outfit_id = outfit_id, object_owner = object_owner, sale_price = new_price }) > 0;
|
||||
}
|
||||
|
||||
public bool DeleteFromObject(uint outfit_id, uint object_id)
|
||||
{
|
||||
return Context.Connection.Execute("DELETE FROM fso_outfits WHERE outfit_id = @outfit_id AND object_owner = @object_owner", new { outfit_id = outfit_id, object_owner = object_id }) > 0;
|
||||
}
|
||||
|
||||
public bool DeleteFromAvatar(uint outfit_id, uint avatar_id)
|
||||
{
|
||||
return Context.Connection.Execute("DELETE FROM fso_outfits WHERE outfit_id = @outfit_id AND avatar_owner = @avatar_owner", new { outfit_id = outfit_id, avatar_owner = avatar_id }) > 0;
|
||||
}
|
||||
|
||||
public List<DbOutfit> GetByAvatarId(uint avatar_id)
|
||||
{
|
||||
return Context.Connection.Query<DbOutfit>("SELECT * FROM fso_outfits WHERE avatar_owner = @avatar_id", new { avatar_id = avatar_id }).ToList();
|
||||
}
|
||||
|
||||
public List<DbOutfit> GetByObjectId(uint object_id)
|
||||
{
|
||||
return Context.Connection.Query<DbOutfit>("SELECT * FROM fso_outfits WHERE object_owner = @object_id", new { object_id = object_id }).ToList();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
12
server/FSO.Server.Database/DA/Relationships/DbRelationship.cs
Executable file
12
server/FSO.Server.Database/DA/Relationships/DbRelationship.cs
Executable file
|
@ -0,0 +1,12 @@
|
|||
namespace FSO.Server.Database.DA.Relationships
|
||||
{
|
||||
public class DbRelationship
|
||||
{
|
||||
public uint from_id { get; set; }
|
||||
public uint to_id { get; set; }
|
||||
public int value { get; set; }
|
||||
public uint index { get; set; }
|
||||
public uint? comment_id { get; set; }
|
||||
public uint date { get; set; }
|
||||
}
|
||||
}
|
12
server/FSO.Server.Database/DA/Relationships/IRelationships.cs
Executable file
12
server/FSO.Server.Database/DA/Relationships/IRelationships.cs
Executable file
|
@ -0,0 +1,12 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Relationships
|
||||
{
|
||||
public interface IRelationships
|
||||
{
|
||||
int UpdateMany(List<DbRelationship> entries);
|
||||
List<DbRelationship> GetOutgoing(uint entity_id);
|
||||
List<DbRelationship> GetBidirectional(uint entity_id);
|
||||
int Delete(uint entity_id);
|
||||
}
|
||||
}
|
84
server/FSO.Server.Database/DA/Relationships/SqlRelationships.cs
Executable file
84
server/FSO.Server.Database/DA/Relationships/SqlRelationships.cs
Executable file
|
@ -0,0 +1,84 @@
|
|||
using Dapper;
|
||||
using FSO.Server.Common;
|
||||
using MySql.Data.MySqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace FSO.Server.Database.DA.Relationships
|
||||
{
|
||||
public class SqlRelationships : AbstractSqlDA, IRelationships
|
||||
{
|
||||
|
||||
public SqlRelationships(ISqlContext context) : base(context)
|
||||
{
|
||||
|
||||
}
|
||||
public int Delete(uint entity_id)
|
||||
{
|
||||
return Context.Connection.ExecuteScalar<int>(
|
||||
"DELETE FROM fso_relationships WHERE from_id = @entity_id OR to_id = @entity_id",
|
||||
new { entity_id = entity_id }
|
||||
);
|
||||
}
|
||||
|
||||
public List<DbRelationship> GetBidirectional(uint entity_id)
|
||||
{
|
||||
return Context.Connection.Query<DbRelationship>(
|
||||
"SELECT * FROM fso_relationships WHERE (from_id = @entity_id AND to_id < 16777216) OR (to_id = @entity_id AND from_id < 16777216)",
|
||||
new { entity_id = entity_id }
|
||||
).ToList();
|
||||
}
|
||||
|
||||
public List<DbRelationship> GetOutgoing(uint entity_id)
|
||||
{
|
||||
return Context.Connection.Query<DbRelationship>(
|
||||
"SELECT * FROM fso_relationships WHERE from_id = @entity_id",
|
||||
new { entity_id = entity_id }
|
||||
).ToList();
|
||||
}
|
||||
|
||||
public int UpdateMany(List<DbRelationship> entries)
|
||||
{
|
||||
var date = Epoch.Now;
|
||||
var conn = (MySqlConnection)Context.Connection;
|
||||
int rows;
|
||||
using (MySqlCommand cmd = new MySqlCommand("", conn))
|
||||
{
|
||||
try
|
||||
{
|
||||
StringBuilder sCommand = new StringBuilder("INSERT INTO fso_relationships (from_id, to_id, value, `index`, `date`) VALUES ");
|
||||
|
||||
bool first = true;
|
||||
foreach (var item in entries)
|
||||
{
|
||||
if (!first) sCommand.Append(",");
|
||||
first = false;
|
||||
sCommand.Append("(");
|
||||
sCommand.Append(item.from_id);
|
||||
sCommand.Append(",");
|
||||
sCommand.Append(item.to_id);
|
||||
sCommand.Append(",");
|
||||
sCommand.Append(item.value);
|
||||
sCommand.Append(",");
|
||||
sCommand.Append(item.index);
|
||||
sCommand.Append(",");
|
||||
sCommand.Append(date);
|
||||
sCommand.Append(")");
|
||||
}
|
||||
sCommand.Append(" ON DUPLICATE KEY UPDATE value = VALUES(`value`); ");
|
||||
|
||||
cmd.CommandTimeout = 300;
|
||||
cmd.CommandText = sCommand.ToString();
|
||||
rows = cmd.ExecuteNonQuery();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
10
server/FSO.Server.Database/DA/Roommates/DbRoommate.cs
Executable file
10
server/FSO.Server.Database/DA/Roommates/DbRoommate.cs
Executable file
|
@ -0,0 +1,10 @@
|
|||
namespace FSO.Server.Database.DA.Roommates
|
||||
{
|
||||
public class DbRoommate
|
||||
{
|
||||
public uint avatar_id { get; set; }
|
||||
public int lot_id { get; set; }
|
||||
public byte permissions_level { get; set; }
|
||||
public byte is_pending { get; set; }
|
||||
}
|
||||
}
|
17
server/FSO.Server.Database/DA/Roommates/IRoommates.cs
Executable file
17
server/FSO.Server.Database/DA/Roommates/IRoommates.cs
Executable file
|
@ -0,0 +1,17 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Roommates
|
||||
{
|
||||
public interface IRoommates
|
||||
{
|
||||
bool Create(DbRoommate roomie);
|
||||
bool CreateOrUpdate(DbRoommate roomie);
|
||||
DbRoommate Get(uint avatar_id, int lot_id);
|
||||
List<DbRoommate> GetAvatarsLots(uint avatar_id);
|
||||
List<DbRoommate> GetLotRoommates(int lot_id);
|
||||
uint RemoveRoommate(uint avatar_id, int lot_id);
|
||||
bool DeclineRoommateRequest(uint avatar_id, int lot_id);
|
||||
bool AcceptRoommateRequest(uint avatar_id, int lot_id);
|
||||
bool UpdatePermissionsLevel(uint avatar_id, int lot_id, byte level);
|
||||
}
|
||||
}
|
77
server/FSO.Server.Database/DA/Roommates/SqlRoommates.cs
Executable file
77
server/FSO.Server.Database/DA/Roommates/SqlRoommates.cs
Executable file
|
@ -0,0 +1,77 @@
|
|||
using Dapper;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
|
||||
namespace FSO.Server.Database.DA.Roommates
|
||||
{
|
||||
public class SqlRoommates : AbstractSqlDA, IRoommates
|
||||
{
|
||||
public SqlRoommates(ISqlContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public bool Create(DbRoommate roomie)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (uint)Context.Connection.Execute("INSERT INTO fso_roommates (avatar_id, lot_id, permissions_level, is_pending) " +
|
||||
" VALUES (@avatar_id, @lot_id, @permissions_level, @is_pending);", roomie) > 0;
|
||||
} catch (SqlException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CreateOrUpdate(DbRoommate roomie)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (uint)Context.Connection.Execute("INSERT INTO fso_roommates (avatar_id, lot_id, permissions_level, is_pending) " +
|
||||
"VALUES (@avatar_id, @lot_id, @permissions_level, @is_pending) " +
|
||||
"ON DUPLICATE KEY UPDATE permissions_level = @permissions_level, is_pending = 0", roomie) > 0;
|
||||
}
|
||||
catch (SqlException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public DbRoommate Get(uint avatar_id, int lot_id)
|
||||
{
|
||||
return Context.Connection.Query<DbRoommate>("SELECT * FROM fso_roommates WHERE avatar_id = @avatar_id AND lot_id = @lot_id",
|
||||
new { avatar_id = avatar_id, lot_id = lot_id }).FirstOrDefault();
|
||||
}
|
||||
public List<DbRoommate> GetAvatarsLots(uint avatar_id)
|
||||
{
|
||||
return Context.Connection.Query<DbRoommate>("SELECT * FROM fso_roommates WHERE avatar_id = @avatar_id",
|
||||
new { avatar_id = avatar_id }).ToList();
|
||||
}
|
||||
public List<DbRoommate> GetLotRoommates(int lot_id)
|
||||
{
|
||||
return Context.Connection.Query<DbRoommate>("SELECT * FROM fso_roommates WHERE lot_id = @lot_id",
|
||||
new { lot_id = lot_id }).ToList();
|
||||
}
|
||||
public uint RemoveRoommate(uint avatar_id, int lot_id)
|
||||
{
|
||||
return (uint)Context.Connection.Execute("DELETE FROM fso_roommates WHERE avatar_id = @avatar_id AND lot_id = @lot_id",
|
||||
new { avatar_id = avatar_id, lot_id = lot_id });
|
||||
}
|
||||
|
||||
public bool DeclineRoommateRequest(uint avatar_id, int lot_id)
|
||||
{
|
||||
return Context.Connection.Execute("DELETE FROM fso_roommates WHERE avatar_id = @avatar_id AND lot_id = @lot_id AND is_pending = 1",
|
||||
new { avatar_id = avatar_id, lot_id = lot_id }) > 0;
|
||||
}
|
||||
public bool AcceptRoommateRequest(uint avatar_id, int lot_id)
|
||||
{
|
||||
return Context.Connection.Execute("UPDATE fso_roommates SET is_pending = 0 WHERE avatar_id = @avatar_id AND lot_id = @lot_id AND is_pending = 1",
|
||||
new { avatar_id = avatar_id, lot_id = lot_id }) > 0;
|
||||
}
|
||||
public bool UpdatePermissionsLevel(uint avatar_id, int lot_id, byte level)
|
||||
{
|
||||
return Context.Connection.Execute("UPDATE fso_roommates SET permissions_level = @level WHERE avatar_id = @avatar_id AND lot_id = @lot_id",
|
||||
new { level = level, avatar_id = avatar_id, lot_id = lot_id }) > 0;
|
||||
}
|
||||
}
|
||||
}
|
15
server/FSO.Server.Database/DA/Shards/IShards.cs
Executable file
15
server/FSO.Server.Database/DA/Shards/IShards.cs
Executable file
|
@ -0,0 +1,15 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace FSO.Server.Database.DA.Shards
|
||||
{
|
||||
public interface IShards
|
||||
{
|
||||
List<Shard> All();
|
||||
|
||||
void CreateTicket(ShardTicket ticket);
|
||||
void DeleteTicket(string ticket_id);
|
||||
ShardTicket GetTicket(string ticket_id);
|
||||
void PurgeTickets(uint time);
|
||||
void UpdateVersion(int shard_id, string name, string number, int? update_id);
|
||||
}
|
||||
}
|
26
server/FSO.Server.Database/DA/Shards/Shard.cs
Executable file
26
server/FSO.Server.Database/DA/Shards/Shard.cs
Executable file
|
@ -0,0 +1,26 @@
|
|||
namespace FSO.Server.Database.DA.Shards
|
||||
{
|
||||
public class Shard
|
||||
{
|
||||
public int shard_id;
|
||||
public string name;
|
||||
public int rank;
|
||||
public string map;
|
||||
public ShardStatus status;
|
||||
public string internal_host;
|
||||
public string public_host;
|
||||
public string version_name;
|
||||
public string version_number;
|
||||
public int? update_id; //new update system. set by whichever server is running the shard.
|
||||
}
|
||||
|
||||
public enum ShardStatus
|
||||
{
|
||||
Up,
|
||||
Down,
|
||||
Busy,
|
||||
Full,
|
||||
Closed,
|
||||
Frontier
|
||||
}
|
||||
}
|
11
server/FSO.Server.Database/DA/Shards/ShardTicket.cs
Executable file
11
server/FSO.Server.Database/DA/Shards/ShardTicket.cs
Executable file
|
@ -0,0 +1,11 @@
|
|||
namespace FSO.Server.Database.DA.Shards
|
||||
{
|
||||
public class ShardTicket
|
||||
{
|
||||
public string ticket_id { get; set; }
|
||||
public uint user_id { get; set; }
|
||||
public uint date { get; set; }
|
||||
public string ip { get; set; }
|
||||
public uint avatar_id { get; set; }
|
||||
}
|
||||
}
|
49
server/FSO.Server.Database/DA/Shards/SqlShards.cs
Executable file
49
server/FSO.Server.Database/DA/Shards/SqlShards.cs
Executable file
|
@ -0,0 +1,49 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Dapper;
|
||||
|
||||
namespace FSO.Server.Database.DA.Shards
|
||||
{
|
||||
public class SqlShards : AbstractSqlDA, IShards
|
||||
{
|
||||
public SqlShards(ISqlContext context) : base(context) {
|
||||
}
|
||||
|
||||
public List<Shard> All()
|
||||
{
|
||||
return Context.Connection.Query<Shard>("SELECT * FROM fso_shards").ToList();
|
||||
}
|
||||
|
||||
public void CreateTicket(ShardTicket ticket)
|
||||
{
|
||||
Context.Connection.Execute("INSERT INTO fso_shard_tickets VALUES (@ticket_id, @user_id, @date, @ip, @avatar_id)", ticket);
|
||||
}
|
||||
|
||||
public void DeleteTicket(string id)
|
||||
{
|
||||
Context.Connection.Execute("DELETE FROM fso_shard_tickets WHERE ticket_id = @ticket_id", new { ticket_id = id });
|
||||
}
|
||||
|
||||
public ShardTicket GetTicket(string id)
|
||||
{
|
||||
return
|
||||
Context.Connection.Query<ShardTicket>("SELECT * FROM fso_shard_tickets WHERE ticket_id = @ticket_id", new { ticket_id = id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public void PurgeTickets(uint time)
|
||||
{
|
||||
Context.Connection.Query("DELETE FROM fso_shard_tickets WHERE date < @time", new { time = time });
|
||||
}
|
||||
|
||||
public void UpdateVersion(int shard_id, string name, string number, int? update_id)
|
||||
{
|
||||
Context.Connection.Query("UPDATE fso_shards SET version_name = @version_name, version_number = @version_number, update_id = @update_id WHERE shard_id = @shard_id", new
|
||||
{
|
||||
version_name = name,
|
||||
version_number = number,
|
||||
update_id = update_id,
|
||||
shard_id = shard_id
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue