add config for irc, geardb management

This commit is contained in:
raphaeIl 2024-05-18 18:00:19 -04:00
parent abe0581f7b
commit 7ad2f87d6b
18 changed files with 889 additions and 22 deletions

View File

@ -51,5 +51,19 @@
return [.. items]; return [.. items];
} }
public static List<GearDB> AddGears(this AccountDB account, SCHALEContext context, params GearDB[] gears)
{
foreach (var gear in gears)
{
gear.AccountServerId = account.ServerId;
context.Gears.Add(gear);
var targetCharacter = account.Characters.FirstOrDefault(x => x.ServerId == gear.BoundCharacterServerId);
targetCharacter.EquipmentServerIds.Add(gear.ServerId);
}
return [.. gears];
}
} }
} }

View File

@ -16,6 +16,7 @@ namespace SCHALE.Common.Database
public DbSet<CharacterDB> Characters { get; set; } public DbSet<CharacterDB> Characters { get; set; }
public DbSet<EquipmentDB> Equipment { get; set; } public DbSet<EquipmentDB> Equipment { get; set; }
public DbSet<WeaponDB> Weapons { get; set; } public DbSet<WeaponDB> Weapons { get; set; }
public DbSet<GearDB> Gears { get; set; }
public DbSet<EchelonDB> Echelons { get; set; } public DbSet<EchelonDB> Echelons { get; set; }
public DbSet<AccountTutorial> AccountTutorials { get; set; } public DbSet<AccountTutorial> AccountTutorials { get; set; }
@ -62,10 +63,16 @@ namespace SCHALE.Common.Database
.WithOne(x => x.Account) .WithOne(x => x.Account)
.HasForeignKey(x => x.AccountServerId) .HasForeignKey(x => x.AccountServerId)
.IsRequired(); .IsRequired();
modelBuilder.Entity<AccountDB>()
.HasMany(x => x.Gears)
.WithOne(x => x.Account)
.HasForeignKey(x => x.AccountServerId)
.IsRequired();
modelBuilder.Entity<ItemDB>().Property(x => x.ServerId).ValueGeneratedOnAdd(); modelBuilder.Entity<ItemDB>().Property(x => x.ServerId).ValueGeneratedOnAdd();
modelBuilder.Entity<EquipmentDB>().Property(x => x.ServerId).ValueGeneratedOnAdd(); modelBuilder.Entity<EquipmentDB>().Property(x => x.ServerId).ValueGeneratedOnAdd();
modelBuilder.Entity<WeaponDB>().Property(x => x.ServerId).ValueGeneratedOnAdd(); modelBuilder.Entity<WeaponDB>().Property(x => x.ServerId).ValueGeneratedOnAdd();
modelBuilder.Entity<GearDB>().Property(x => x.ServerId).ValueGeneratedOnAdd();
modelBuilder.Entity<EchelonDB>().Property(x => x.ServerId).ValueGeneratedOnAdd(); modelBuilder.Entity<EchelonDB>().Property(x => x.ServerId).ValueGeneratedOnAdd();

View File

@ -209,6 +209,10 @@ namespace SCHALE.Common.Database
[JsonIgnore] [JsonIgnore]
public virtual ICollection<WeaponDB> Weapons { get; } public virtual ICollection<WeaponDB> Weapons { get; }
[JsonIgnore]
public virtual ICollection<GearDB> Gears { get; }
[JsonIgnore] [JsonIgnore]
public long RaidSeasonId { get; set; } // idk where to store this public long RaidSeasonId { get; set; } // idk where to store this
@ -1094,7 +1098,7 @@ namespace SCHALE.Common.Database
} }
public class EliminateRaidLobbyInfoDB public class EliminateRaidLobbyInfoDB : RaidLobbyInfoDB
{ {
public List<string> OpenedBossGroups { get; set; } public List<string> OpenedBossGroups { get; set; }
public Dictionary<string, long> BestRankingPointPerBossGroup { get; set; } public Dictionary<string, long> BestRankingPointPerBossGroup { get; set; }
@ -1456,19 +1460,44 @@ namespace SCHALE.Common.Database
public class GearDB : ParcelBase public class GearDB : ParcelBase
{ {
[NotMapped]
public override ParcelType Type { get => ParcelType.CharacterGear; } public override ParcelType Type { get => ParcelType.CharacterGear; }
[NotMapped]
[JsonIgnore] [JsonIgnore]
public override IEnumerable<ParcelInfo> ParcelInfos { get; } public override IEnumerable<ParcelInfo> ParcelInfos { get; }
[JsonIgnore]
public virtual AccountDB Account { get; set; }
[JsonIgnore]
public long AccountServerId { get; set; }
[Key]
public long ServerId { get; set; } public long ServerId { get; set; }
public long UniqueId { get; set; } public long UniqueId { get; set; }
public int Level { get; set; } public int Level { get; set; }
public long Exp { get; set; } public long Exp { get; set; }
public int Tier { get; set; } public int Tier { get; set; }
public long SlotIndex { get; set; } public long SlotIndex { get; set; }
public long BoundCharacterServerId { get; set; } public long BoundCharacterServerId { get; set; }
public EquipmentDB ToEquipmentDB { get; set; }
[NotMapped]
public EquipmentDB ToEquipmentDB { get {
return new()
{
IsNew = true,
ServerId = ServerId,
BoundCharacterServerId = BoundCharacterServerId,
Tier = Tier,
Level = Level,
StackCount = 1,
Exp = Exp
};
}
}
} }
@ -1895,6 +1924,7 @@ namespace SCHALE.Common.Database
public DateTime NextSeasonEndDate { get; set; } public DateTime NextSeasonEndDate { get; set; }
public DateTime NextSettlementEndDate { get; set; } public DateTime NextSettlementEndDate { get; set; }
public ClanAssistUseInfo ClanAssistUseInfo { get; set; } public ClanAssistUseInfo ClanAssistUseInfo { get; set; }
public Dictionary<int, bool> RemainFailCompensation { get; set; }
} }

View File

@ -0,0 +1,521 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using SCHALE.Common.Database;
#nullable disable
namespace SCHALE.Common.Migrations
{
[DbContext(typeof(SCHALEContext))]
[Migration("20240518014039_Gears")]
partial class Gears
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Proxies:ChangeTracking", false)
.HasAnnotation("Proxies:CheckEquality", false)
.HasAnnotation("Proxies:LazyLoading", true)
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("SCHALE.Common.Database.AccountDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<DateTime?>("BirthDay")
.HasColumnType("datetime2");
b.Property<string>("CallName")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CallNameUpdateTime")
.HasColumnType("datetime2");
b.Property<string>("Comment")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CreateDate")
.HasColumnType("datetime2");
b.Property<string>("DevId")
.HasColumnType("nvarchar(max)");
b.Property<long>("Exp")
.HasColumnType("bigint");
b.Property<DateTime>("LastConnectTime")
.HasColumnType("datetime2");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<DateTime?>("LinkRewardDate")
.HasColumnType("datetime2");
b.Property<int>("LobbyMode")
.HasColumnType("int");
b.Property<long>("MemoryLobbyUniqueId")
.HasColumnType("bigint");
b.Property<string>("Nickname")
.HasColumnType("nvarchar(max)");
b.Property<long>("PublisherAccountId")
.HasColumnType("bigint");
b.Property<long>("RaidSeasonId")
.HasColumnType("bigint");
b.Property<int>("RepresentCharacterServerId")
.HasColumnType("int");
b.Property<int?>("RetentionDays")
.HasColumnType("int");
b.Property<int>("State")
.HasColumnType("int");
b.Property<int?>("UnReadMailCount")
.HasColumnType("int");
b.Property<int?>("VIPLevel")
.HasColumnType("int");
b.HasKey("ServerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("SCHALE.Common.Database.CharacterDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<string>("EquipmentServerIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("EquipmentSlotAndDBIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("ExSkillLevel")
.HasColumnType("int");
b.Property<long>("Exp")
.HasColumnType("bigint");
b.Property<int>("ExtraPassiveSkillLevel")
.HasColumnType("int");
b.Property<long>("FavorExp")
.HasColumnType("bigint");
b.Property<int>("FavorRank")
.HasColumnType("int");
b.Property<bool>("IsFavorite")
.HasColumnType("bit");
b.Property<bool>("IsLocked")
.HasColumnType("bit");
b.Property<int>("LeaderSkillLevel")
.HasColumnType("int");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<int>("PassiveSkillLevel")
.HasColumnType("int");
b.Property<string>("PotentialStats")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("PublicSkillLevel")
.HasColumnType("int");
b.Property<int>("StarGrade")
.HasColumnType("int");
b.Property<long>("UniqueId")
.HasColumnType("bigint");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Characters");
});
modelBuilder.Entity("SCHALE.Common.Database.EchelonDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<long>("EchelonNumber")
.HasColumnType("bigint");
b.Property<int>("EchelonType")
.HasColumnType("int");
b.Property<int>("ExtensionType")
.HasColumnType("int");
b.Property<long>("LeaderServerId")
.HasColumnType("bigint");
b.Property<string>("MainSlotServerIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("SkillCardMulliganCharacterIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("SupportSlotServerIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<long>("TSSInteractionServerId")
.HasColumnType("bigint");
b.Property<int>("UsingFlag")
.HasColumnType("int");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Echelons");
});
modelBuilder.Entity("SCHALE.Common.Database.EquipmentDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<long>("BoundCharacterServerId")
.HasColumnType("bigint");
b.Property<long>("Exp")
.HasColumnType("bigint");
b.Property<bool>("IsLocked")
.HasColumnType("bit");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<long>("StackCount")
.HasColumnType("bigint");
b.Property<int>("Tier")
.HasColumnType("int");
b.Property<long>("UniqueId")
.HasColumnType("bigint");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Equipment");
});
modelBuilder.Entity("SCHALE.Common.Database.GearDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<long>("BoundCharacterServerId")
.HasColumnType("bigint");
b.Property<long>("Exp")
.HasColumnType("bigint");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<long>("SlotIndex")
.HasColumnType("bigint");
b.Property<int>("Tier")
.HasColumnType("int");
b.Property<long>("UniqueId")
.HasColumnType("bigint");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Gears");
});
modelBuilder.Entity("SCHALE.Common.Database.ItemDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<bool>("IsLocked")
.HasColumnType("bit");
b.Property<long>("StackCount")
.HasColumnType("bigint");
b.Property<long>("UniqueId")
.HasColumnType("bigint");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Items");
});
modelBuilder.Entity("SCHALE.Common.Database.MissionProgressDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<bool>("Complete")
.HasColumnType("bit");
b.Property<long>("MissionUniqueId")
.HasColumnType("bigint");
b.Property<string>("ProgressParameters")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("StartTime")
.HasColumnType("datetime2");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("MissionProgresses");
});
modelBuilder.Entity("SCHALE.Common.Database.Models.AccountTutorial", b =>
{
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<string>("TutorialIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("AccountServerId");
b.ToTable("AccountTutorials");
});
modelBuilder.Entity("SCHALE.Common.Database.Models.GuestAccount", b =>
{
b.Property<long>("Uid")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Uid"));
b.Property<string>("DeviceId")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Token")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Uid");
b.ToTable("GuestAccounts");
});
modelBuilder.Entity("SCHALE.Common.Database.WeaponDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<long>("BoundCharacterServerId")
.HasColumnType("bigint");
b.Property<long>("Exp")
.HasColumnType("bigint");
b.Property<bool>("IsLocked")
.HasColumnType("bit");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<int>("StarGrade")
.HasColumnType("int");
b.Property<long>("UniqueId")
.HasColumnType("bigint");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Weapons");
});
modelBuilder.Entity("SCHALE.Common.Database.CharacterDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Characters")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.EchelonDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Echelons")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.EquipmentDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Equipment")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.GearDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Gears")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.ItemDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Items")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.MissionProgressDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("MissionProgresses")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.WeaponDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Weapons")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.AccountDB", b =>
{
b.Navigation("Characters");
b.Navigation("Echelons");
b.Navigation("Equipment");
b.Navigation("Gears");
b.Navigation("Items");
b.Navigation("MissionProgresses");
b.Navigation("Weapons");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,51 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace SCHALE.Common.Migrations
{
/// <inheritdoc />
public partial class Gears : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Gears",
columns: table => new
{
ServerId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
AccountServerId = table.Column<long>(type: "bigint", nullable: false),
UniqueId = table.Column<long>(type: "bigint", nullable: false),
Level = table.Column<int>(type: "int", nullable: false),
Exp = table.Column<long>(type: "bigint", nullable: false),
Tier = table.Column<int>(type: "int", nullable: false),
SlotIndex = table.Column<long>(type: "bigint", nullable: false),
BoundCharacterServerId = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Gears", x => x.ServerId);
table.ForeignKey(
name: "FK_Gears_Accounts_AccountServerId",
column: x => x.AccountServerId,
principalTable: "Accounts",
principalColumn: "ServerId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Gears_AccountServerId",
table: "Gears",
column: "AccountServerId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Gears");
}
}
}

View File

@ -254,6 +254,42 @@ namespace SCHALE.Common.Migrations
b.ToTable("Equipment"); b.ToTable("Equipment");
}); });
modelBuilder.Entity("SCHALE.Common.Database.GearDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<long>("BoundCharacterServerId")
.HasColumnType("bigint");
b.Property<long>("Exp")
.HasColumnType("bigint");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<long>("SlotIndex")
.HasColumnType("bigint");
b.Property<int>("Tier")
.HasColumnType("int");
b.Property<long>("UniqueId")
.HasColumnType("bigint");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Gears");
});
modelBuilder.Entity("SCHALE.Common.Database.ItemDB", b => modelBuilder.Entity("SCHALE.Common.Database.ItemDB", b =>
{ {
b.Property<long>("ServerId") b.Property<long>("ServerId")
@ -416,6 +452,17 @@ namespace SCHALE.Common.Migrations
b.Navigation("Account"); b.Navigation("Account");
}); });
modelBuilder.Entity("SCHALE.Common.Database.GearDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Gears")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.ItemDB", b => modelBuilder.Entity("SCHALE.Common.Database.ItemDB", b =>
{ {
b.HasOne("SCHALE.Common.Database.AccountDB", "Account") b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
@ -457,6 +504,8 @@ namespace SCHALE.Common.Migrations
b.Navigation("Equipment"); b.Navigation("Equipment");
b.Navigation("Gears");
b.Navigation("Items"); b.Navigation("Items");
b.Navigation("MissionProgresses"); b.Navigation("MissionProgresses");

View File

@ -6,12 +6,12 @@ using SCHALE.GameServer.Services.Irc;
namespace SCHALE.GameServer.Commands namespace SCHALE.GameServer.Commands
{ {
[CommandHandler("inventory", "Command to manage inventory (chars, weapons, equipment, items)", "/inventory <addall|clearall>")] [CommandHandler("inventory", "Command to manage inventory (chars, weapons, equipment, items)", "/inventory <addall|removeall>")]
internal class InventoryCommand : Command internal class InventoryCommand : Command
{ {
public InventoryCommand(IrcConnection connection, string[] args, bool validate = true) : base(connection, args, validate) { } public InventoryCommand(IrcConnection connection, string[] args, bool validate = true) : base(connection, args, validate) { }
[Argument(0, @"^addall$|^clearall$", "The operation selected (addall, clearall)", ArgumentFlags.IgnoreCase)] [Argument(0, @"^addall$|^removeall$", "The operation selected (addall, removeall)", ArgumentFlags.IgnoreCase)]
public string Op { get; set; } = string.Empty; public string Op { get; set; } = string.Empty;
public override void Execute() public override void Execute()
@ -25,13 +25,19 @@ namespace SCHALE.GameServer.Commands
InventoryUtils.AddAllWeapons(connection); InventoryUtils.AddAllWeapons(connection);
InventoryUtils.AddAllEquipment(connection); InventoryUtils.AddAllEquipment(connection);
InventoryUtils.AddAllItems(connection); InventoryUtils.AddAllItems(connection);
InventoryUtils.AddAllGears(connection);
connection.SendChatMessage("Added Everything!");
break; break;
case "clearall": case "removeall":
InventoryUtils.RemoveAllCharacters(connection); InventoryUtils.RemoveAllCharacters(connection);
context.Weapons.RemoveRange(context.Weapons.Where(x => x.AccountServerId == connection.AccountServerId)); context.Weapons.RemoveRange(context.Weapons.Where(x => x.AccountServerId == connection.AccountServerId));
context.Equipment.RemoveRange(context.Equipment.Where(x => x.AccountServerId == connection.AccountServerId)); context.Equipment.RemoveRange(context.Equipment.Where(x => x.AccountServerId == connection.AccountServerId));
context.Items.RemoveRange(context.Items.Where(x => x.AccountServerId == connection.AccountServerId)); context.Items.RemoveRange(context.Items.Where(x => x.AccountServerId == connection.AccountServerId));
context.Gears.RemoveRange(context.Gears.Where(x => x.AccountServerId == connection.AccountServerId));
connection.SendChatMessage("Removed Everything!");
break; break;
} }

View File

@ -2,15 +2,16 @@
using SCHALE.GameServer.Services.Irc; using SCHALE.GameServer.Services.Irc;
using System.ComponentModel; using System.ComponentModel;
using System.Reflection; using System.Reflection;
using SCHALE.GameServer.Utils;
namespace SCHALE.GameServer.Commands namespace SCHALE.GameServer.Commands
{ {
[CommandHandler("setaccount", "Command to change player's account data", "/setaccount <|Level|Nickname|RaidSeasonId|Property|...> <Value>")] [CommandHandler("setaccount", "Command to change player's account data (case-sensitive)", "/setaccount <|Level|Nickname|RaidSeasonId|Property|...> <Value>")]
internal class SetAccountCommand : Command internal class SetAccountCommand : Command
{ {
public SetAccountCommand(IrcConnection connection, string[] args, bool validate = true) : base(connection, args, validate) { } public SetAccountCommand(IrcConnection connection, string[] args, bool validate = true) : base(connection, args, validate) { }
[Argument(0, @"^[a-zA-Z]+$", "The Account Property you want to change.", ArgumentFlags.IgnoreCase)] [Argument(0, @"^[a-zA-Z]+$", "The Account Property you want to change. (case-sensitive)", ArgumentFlags.IgnoreCase)]
public string Property { get; set; } = string.Empty; public string Property { get; set; } = string.Empty;
[Argument(1, @"", "The value you want to change it to, must match the property type.", ArgumentFlags.IgnoreCase)] [Argument(1, @"", "The value you want to change it to, must match the property type.", ArgumentFlags.IgnoreCase)]
@ -18,7 +19,7 @@ namespace SCHALE.GameServer.Commands
public override void Execute() public override void Execute()
{ {
PropertyInfo? targetProperty = typeof(AccountDB).GetProperty(Property); PropertyInfo? targetProperty = typeof(AccountDB).GetProperty(Property) ?? typeof(AccountDB).GetProperty(Property.Capitalize());
if (targetProperty != null) if (targetProperty != null)
{ {
@ -31,17 +32,20 @@ namespace SCHALE.GameServer.Commands
object targetValue = converter.ConvertFromString(Value); object targetValue = converter.ConvertFromString(Value);
targetProperty.SetValue(connection.Account, targetValue); targetProperty.SetValue(connection.Account, targetValue);
connection.Context.SaveChanges();
connection.SendChatMessage($"Set Player with UID {connection.AccountServerId}'s {Property} to {Value}");
} catch (Exception) } catch (Exception)
{ {
throw new ArgumentException("Invalid Value"); throw new ArgumentException("Invalid Value");
} }
} }
} else }
else
{ {
throw new ArgumentException("Invalid Player Property!"); throw new ArgumentException("Invalid Player Property!");
} }
} }
} }
} }

View File

@ -320,6 +320,11 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
EquipmentDBs = [.. account.Equipment] EquipmentDBs = [.. account.Equipment]
}, },
CharacterGearListResponse = new CharacterGearListResponse()
{
GearDBs = [.. account.Gears]
},
ClanLoginResponse = new ClanLoginResponse() ClanLoginResponse = new ClanLoginResponse()
{ {
AccountClanMemberDB = new() AccountClanMemberDB = new()
@ -328,6 +333,16 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
} }
}, },
EliminateRaidLoginResponse = new EliminateRaidLoginResponse()
{
SeasonType = RaidSeasonType.Open,
SweepPointByRaidUniqueId = new()
{
{ 2041104, int.MaxValue },
{ 2041204, int.MaxValue }
}
},
FriendCode = "SCHALE", FriendCode = "SCHALE",
}; };
} }
@ -445,13 +460,6 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
{ {
return new MiniGameMissionListResponse(); return new MiniGameMissionListResponse();
} }
// these will probably be commands
private void SetRaidSeason(AccountDB account, long seasonId)
{
account.RaidSeasonId = seasonId;
context.SaveChanges();
}
} }
} }

View File

@ -0,0 +1,66 @@
using SCHALE.Common.Database;
using SCHALE.Common.Database.ModelExtensions;
using SCHALE.Common.FlatData;
using SCHALE.Common.NetworkProtocol;
using SCHALE.GameServer.Services;
namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
{
public class CharacterGear : ProtocolHandlerBase
{
private readonly ISessionKeyService sessionKeyService;
private readonly SCHALEContext context;
private readonly ExcelTableService excelTableService;
public CharacterGear(IProtocolHandlerFactory protocolHandlerFactory, ISessionKeyService _sessionKeyService, SCHALEContext _context, ExcelTableService _excelTableService) : base(protocolHandlerFactory)
{
sessionKeyService = _sessionKeyService;
context = _context;
excelTableService = _excelTableService;
}
[ProtocolHandler(Protocol.CharacterGear_Unlock)]
public ResponsePacket UnlockHandler(CharacterGearUnlockRequest req)
{
var account = sessionKeyService.GetAccount(req.SessionKey);
var gearExcelTable = excelTableService.GetTable<CharacterGearExcelTable>().UnPack().DataList;
var targetCharacter = account.Characters.FirstOrDefault(x => x.ServerId == req.CharacterServerId);
var gearId = gearExcelTable.FirstOrDefault(x => x.CharacterId == targetCharacter.UniqueId).Id;
var newGear = new GearDB()
{
UniqueId = gearId,
Level = 1,
SlotIndex = req.SlotIndex,
BoundCharacterServerId = req.CharacterServerId,
Tier = 1,
Exp = 0,
};
account.AddGears(context, [newGear]);
context.SaveChanges();
return new CharacterGearUnlockResponse()
{
GearDB = newGear,
CharacterDB = targetCharacter,
};
}
[ProtocolHandler(Protocol.CharacterGear_TierUp)]
public ResponsePacket TierUpHandler(CharacterGearTierUpRequest req)
{ // doesnt work
var targetGear = context.Gears.FirstOrDefault(x => x.ServerId == req.GearServerId);
targetGear.Tier++;
context.SaveChanges();
return new CharacterGearTierUpResponse()
{
GearDB = targetGear,
};
}
}
}

View File

@ -1,6 +1,7 @@
using SCHALE.Common.Database; using SCHALE.Common.Database;
using SCHALE.Common.NetworkProtocol; using SCHALE.Common.NetworkProtocol;
using SCHALE.GameServer.Services; using SCHALE.GameServer.Services;
using SCHALE.GameServer.Utils;
namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
{ {
@ -26,8 +27,8 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
{ {
IrcConfig = new() IrcConfig = new()
{ {
HostAddress = REPLACE WITH YOUR IP, HostAddress = Config.Instance.Address,
Port = 6667, Port = Config.Instance.Port,
Password = "" Password = ""
}, },
AccountClanDB = new() AccountClanDB = new()

View File

@ -8,6 +8,8 @@ using SCHALE.GameServer.Services;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using SCHALE.GameServer.Services.Irc; using SCHALE.GameServer.Services.Irc;
using SCHALE.GameServer.Commands; using SCHALE.GameServer.Commands;
using SCHALE.GameServer.Utils;
using System.Net.NetworkInformation;
namespace SCHALE.GameServer namespace SCHALE.GameServer
{ {
@ -47,6 +49,15 @@ namespace SCHALE.GameServer
// Load Commands // Load Commands
CommandFactory.LoadCommands(); CommandFactory.LoadCommands();
// Load Config
Config.Load();
if (Config.Instance.Address == "127.0.0.1")
{
Config.Instance.Address = NetworkInterface.GetAllNetworkInterfaces().Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback && i.OperationalStatus == OperationalStatus.Up).First().GetIPProperties().UnicastAddresses.Where(a => a.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).First().Address.ToString();
Config.Save();
}
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<KestrelServerOptions>(op => op.AllowSynchronousIO = true); builder.Services.Configure<KestrelServerOptions>(op => op.AllowSynchronousIO = true);

View File

@ -22,12 +22,12 @@ namespace SCHALE.GameServer.Services.Irc
public void SendChatMessage(string text) public void SendChatMessage(string text)
{ {
SendChatMessage(text, "Shiroko", 10010, 0, IrcMessageType.Chat); SendChatMessage(text, "Arona", 19009113, 0, IrcMessageType.Chat);
} }
public void SendEmote(long stickerId) public void SendEmote(long stickerId)
{ {
SendChatMessage("", "Shiroko", 10010, stickerId, IrcMessageType.Sticker); SendChatMessage("", "Arona", 19009113, stickerId, IrcMessageType.Sticker);
} }
public void SendChatMessage(string text, string nickname, long pfpCharacterId, long stickerId, IrcMessageType messageType) public void SendChatMessage(string text, string nickname, long pfpCharacterId, long stickerId, IrcMessageType messageType)

View File

@ -163,6 +163,7 @@ namespace SCHALE.GameServer.Services.Irc
{ {
Command? cmd = CommandFactory.CreateCommand(cmdStr, connection, cmdStrings[1..]); Command? cmd = CommandFactory.CreateCommand(cmdStr, connection, cmdStrings[1..]);
if (cmd is null) if (cmd is null)
{ {
connection.SendChatMessage($"Invalid command {cmdStr}, try /help"); connection.SendChatMessage($"Invalid command {cmdStr}, try /help");
@ -174,7 +175,10 @@ namespace SCHALE.GameServer.Services.Irc
} }
catch (Exception ex) catch (Exception ex)
{ {
var cmdAtr = (CommandHandlerAttribute?)Attribute.GetCustomAttribute(CommandFactory.commands[cmdStr], typeof(CommandHandlerAttribute));
connection.SendChatMessage($"Command {cmdStr} failed to execute!, " + ex.Message); connection.SendChatMessage($"Command {cmdStr} failed to execute!, " + ex.Message);
connection.SendChatMessage($"Usage: {cmdAtr.Usage}");
} }
} }
} }

View File

@ -0,0 +1,32 @@
using Serilog;
using System.Text.Json;
namespace SCHALE.GameServer.Utils
{
public class Config : Singleton<Config>
{
public static string ConfigPath => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json");
public string Address { get; set; } = "127.0.0.1";
public int Port { get; set; } = 6667;
public static void Load()
{
if (!File.Exists(ConfigPath))
Save();
string json = File.ReadAllText(ConfigPath);
Instance = JsonSerializer.Deserialize<Config>(json);
Log.Debug($"Config loaded");
}
public static void Save()
{
File.WriteAllText(ConfigPath, JsonSerializer.Serialize(Instance));
Log.Debug($"Config saved");
}
}
}

View File

@ -1,6 +1,7 @@
using SCHALE.Common.Database; using SCHALE.Common.Database;
using SCHALE.Common.Database.ModelExtensions; using SCHALE.Common.Database.ModelExtensions;
using SCHALE.Common.FlatData; using SCHALE.Common.FlatData;
using SCHALE.Common.Migrations;
using SCHALE.GameServer.Services; using SCHALE.GameServer.Services;
using SCHALE.GameServer.Services.Irc; using SCHALE.GameServer.Services.Irc;
using System; using System;
@ -23,6 +24,8 @@ namespace SCHALE.Common.Utils
account.AddCharacters(context, [.. allCharacters]); account.AddCharacters(context, [.. allCharacters]);
context.SaveChanges(); context.SaveChanges();
connection.SendChatMessage("Added all characters!");
} }
public static void AddAllEquipment(IrcConnection connection) public static void AddAllEquipment(IrcConnection connection)
@ -40,6 +43,8 @@ namespace SCHALE.Common.Utils
connection.Account.AddEquipment(connection.Context, [.. allEquipment]); connection.Account.AddEquipment(connection.Context, [.. allEquipment]);
connection.Context.SaveChanges(); connection.Context.SaveChanges();
connection.SendChatMessage("Added all equipment!");
} }
public static void AddAllItems(IrcConnection connection) public static void AddAllItems(IrcConnection connection)
@ -57,6 +62,8 @@ namespace SCHALE.Common.Utils
connection.Account.AddItems(connection.Context, [.. allItems]); connection.Account.AddItems(connection.Context, [.. allItems]);
connection.Context.SaveChanges(); connection.Context.SaveChanges();
connection.SendChatMessage("Added all items!");
} }
public static void AddAllWeapons(IrcConnection connection) public static void AddAllWeapons(IrcConnection connection)
@ -79,8 +86,34 @@ namespace SCHALE.Common.Utils
account.AddWeapons(context, [.. allWeapons]); account.AddWeapons(context, [.. allWeapons]);
context.SaveChanges(); context.SaveChanges();
connection.SendChatMessage("Added all weapons!");
} }
public static void AddAllGears(IrcConnection connection)
{
var account = connection.Account;
var context = connection.Context;
var gearExcel = connection.ExcelTableService.GetTable<CharacterGearExcelTable>().UnPack().DataList;
var allGears = gearExcel.Where(x => x.Tier == 2 && context.Characters.Any(y => y.UniqueId == x.CharacterId)).Select(x => new GearDB()
{
UniqueId = x.Id,
Level = 1,
SlotIndex = 4,
BoundCharacterServerId = context.Characters.FirstOrDefault(z => z.UniqueId == x.CharacterId).ServerId,
Tier = 2,
Exp = 0,
});
account.AddGears(context, [.. allGears]);
context.SaveChanges();
connection.SendChatMessage("Added all gears!");
}
public static void RemoveAllCharacters(IrcConnection connection) // removing default characters breaks game public static void RemoveAllCharacters(IrcConnection connection) // removing default characters breaks game
{ {
var characterDB = connection.Context.Characters; var characterDB = connection.Context.Characters;
@ -89,6 +122,8 @@ namespace SCHALE.Common.Utils
var removed = characterDB.Where(x => x.AccountServerId == connection.AccountServerId && !defaultCharacters.Contains(x.UniqueId)); var removed = characterDB.Where(x => x.AccountServerId == connection.AccountServerId && !defaultCharacters.Contains(x.UniqueId));
characterDB.RemoveRange(removed); characterDB.RemoveRange(removed);
connection.SendChatMessage("Removed all characters!");
} }
public static CharacterDB CreateMaxCharacterFromId(long characterId) public static CharacterDB CreateMaxCharacterFromId(long characterId)

View File

@ -0,0 +1,18 @@
namespace SCHALE.GameServer.Utils
{
public abstract class Singleton<T> where T : new()
{
static T instance;
public static T Instance
{
get
{
if (instance == null)
instance = new T();
return instance;
}
set => instance = value;
}
}
}

View File

@ -0,0 +1,10 @@
namespace SCHALE.GameServer.Utils
{
public static class StringExtension
{
public static string Capitalize(this string str)
{
return char.ToUpperInvariant(str[0]) + str.Substring(1);
}
}
}