implement basic gacha ( no droprates yet)

This commit is contained in:
raphaeIl
2024-04-05 21:02:31 -04:00
parent bbe0d7ab11
commit 92907806b2
11 changed files with 606 additions and 108 deletions

View File

@@ -3,6 +3,7 @@ using BLHX.Server.Common.Database;
using BLHX.Server.Common.Proto.common;
using BLHX.Server.Common.Utils;
using BLHX.Server.Game.Handlers;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
namespace BLHX.Server.Game.Commands {
[CommandHandler("ship", "Unlock a character or all characters", "ship unlock=all rarity=6")]
@@ -33,6 +34,9 @@ namespace BLHX.Server.Game.Commands {
List<PlayerShip> all_ships = all_ship_ids.Select(ship_id => CreateShipFromId((uint)ship_id, connection.player.Uid)).Take(amount).ToList();
foreach (int id in all_ship_ids)
Logger.c.Log(id + "");
all_ships.AddRange(GetDefaultShips(connection.player.Ships)); // add the defaults
connection.player.Ships = all_ships;
connection.SendSystemMsg($"Added {amount} ships!");

View File

@@ -2,18 +2,15 @@
using BLHX.Server.Common.Database;
using BLHX.Server.Common.Proto;
using BLHX.Server.Common.Data;
using BLHX.Server.Common.Utils;
namespace BLHX.Server.Game.Handlers
{
internal static class P10
{
namespace BLHX.Server.Game.Handlers {
internal static class P10 {
#region GateCommands
[PacketHandler(Command.Cs10800)]
static void VersionHandler(Connection connection, Packet packet)
{
static void VersionHandler(Connection connection, Packet packet) {
var req = packet.Decode<Cs10800>();
connection.Send(new Sc10801()
{
connection.Send(new Sc10801() {
GatewayIp = Config.Instance.Address,
GatewayPort = Config.Instance.Port,
Url = "http://" + Config.Instance.Address,
@@ -37,14 +34,12 @@ namespace BLHX.Server.Game.Handlers
}
[PacketHandler(Command.Cs10020)]
static void UserLoginHandler(Connection connection, Packet packet)
{
static void UserLoginHandler(Connection connection, Packet packet) {
// Arg2 uid
// Arg3 accessToken
// CheckKey md5(Arg1 + salt)
var req = packet.Decode<Cs10020>();
connection.Send(new Sc10021()
{
connection.Send(new Sc10021() {
Result = 0,
AccountId = uint.Parse(req.Arg2),
Serverlists = [
@@ -65,14 +60,12 @@ namespace BLHX.Server.Game.Handlers
#endregion
[PacketHandler(Command.Cs10022)]
static void ServerLoginHandler(Connection connection, Packet packet)
{
static void ServerLoginHandler(Connection connection, Packet packet) {
var req = packet.Decode<Cs10022>();
var rsp = new Sc10023();
var account = DBManager.AccountContext.Accounts.SingleOrDefault(x => x.Uid == req.AccountId);
if (account is null || account.Token != req.ServerTicket)
{
if (account is null || account.Token != req.ServerTicket) {
rsp.Result = 1;
connection.Send(rsp);
connection.EndProtocol();
@@ -83,8 +76,7 @@ namespace BLHX.Server.Game.Handlers
rsp.ServerTicket = req.ServerTicket;
var player = DBManager.PlayerContext.Players.SingleOrDefault(x => x.Token == req.ServerTicket);
if (player is null)
{
if (player is null) {
connection.Send(rsp);
return;
}
@@ -96,12 +88,10 @@ namespace BLHX.Server.Game.Handlers
}
[PacketHandler(Command.Cs10024)]
static void CreateNewPlayerHandler(Connection connection, Packet packet)
{
static void CreateNewPlayerHandler(Connection connection, Packet packet) {
var req = packet.Decode<Cs10024>();
var rsp = new Sc10025();
if (connection.player is not null)
{
if (connection.player is not null) {
rsp.Result = 1011;
connection.Send(rsp);
return;
@@ -114,10 +104,21 @@ namespace BLHX.Server.Game.Handlers
}
[PacketHandler(Command.Cs10100, IsNotifyHandler = true)]
static void HeartbeatHandler(Connection connection, Packet packet)
{
static void HeartbeatHandler(Connection connection, Packet packet) {
connection.Send(new Sc10101());
connection.Tick();
}
[PacketHandler(Command.Cs10992)]
static void LevelUpHandler(Connection connection, Packet packet) {
var req = packet.Decode<Cs10992>();
Logger.c.Log("TrackType: " + req.TrackType);
Logger.c.Log("EventId: " + req.EventId);
Logger.c.Log("Para1: " + req.Para1);
Logger.c.Log("Para2: " + req.Para2);
Logger.c.Log("Para3: " + req.Para3);
}
}
}

View File

@@ -31,6 +31,13 @@ namespace BLHX.Server.Game.Handlers {
connection.Send(new Sc11014());
}
[PacketHandler(Command.Cs11019, SaveDataAfterRun = true)]
static void UpdateCommonFlagHandler(Connection connection, Packet packet) {
var req = packet.Decode<Cs11019>();
connection.Send(new Sc11020());
}
[PacketHandler(Command.Cs11601)]
static void GetEmojiInfoHandler(Connection connection, Packet packet) {
connection.Send(new Sc11602());

View File

@@ -2,6 +2,10 @@
using BLHX.Server.Common.Proto.p12;
using BLHX.Server.Common.Utils;
using BLHX.Server.Common.Proto.common;
using BLHX.Server.Common.Proto.p11;
using BLHX.Server.Common.Data;
using BLHX.Server.Common.Database;
using BLHX.Server.Game.Managers;
namespace BLHX.Server.Game.Handlers {
internal static class P12 {
@@ -28,29 +32,62 @@ namespace BLHX.Server.Game.Handlers {
}
[PacketHandler(Command.Cs12002, SaveDataAfterRun = true)]
static void BuildHandler(Connection connection, Packet packet) {
static void BuildShipHandler(Connection connection, Packet packet) {
var req = packet.Decode<Cs12002>();
Logger.c.Log("Id: " + req.Id);
Logger.c.Log("Cost Type: " + req.Costtype);
Logger.c.Log("Count: " + req.Count);
// Id: gacha banner id
// Count: number of batch builds
// cost type: 1 wisdom cube + 1500 coin for each gacha i guess?
// TODO: remove the resources used from player resources
connection.Send(new Sc12003() {
BuildInfoes = [
new Buildinfo() { BuildId = req.Id, FinishTime = 0, Time = 0 },
]
if (!BuildManager.Instance.BatchBuildShip(req.Id, req.Count))
Logger.c.Log("Build capacity is full or something went wrong");
connection.Send(new Sc12003() {
BuildInfoes = BuildManager.Instance.ToBuildInfoes()
});
}
[PacketHandler(Command.Cs12008, SaveDataAfterRun = true)]
static void FinishBuildHandler(Connection connection, Packet packet) {
static void BuildShipImmediatelyHandler(Connection connection, Packet packet) {
var req = packet.Decode<Cs12008>();
connection.Send(new Sc12009() { PosLists = req.PosLists });
}
[PacketHandler(Command.Cs12043, SaveDataAfterRun = true)]
static void GetShipHandler(Connection connection, Packet packet) {
var req = packet.Decode<Cs12043>();
// pos: position in build, Tid: banner id?
connection.Send(new Sc12044() {
infoLists = BuildManager.Instance.ToInfoLists()
});
}
[PacketHandler(Command.Cs12025, SaveDataAfterRun = true)]
static void GetShipAfterHandler(Connection connection, Packet packet) {
var req = packet.Decode<Cs12025>();
connection.Send(new Sc12026() {
ShipLists = BuildManager.Instance.GetBuildResults(req.PosLists, connection.player.Uid)
});
}
[PacketHandler(Command.Cs12045, SaveDataAfterRun = true)]
static void GetShipConfirmHandler(Connection connection, Packet packet) {
var req = packet.Decode<Cs12045>();
BuildManager.Instance.ClearBuilds();
connection.Send(new Sc12046());
}
}
static class P12ConnectionNotifyExtensions {
@@ -76,7 +113,15 @@ namespace BLHX.Server.Game.Handlers {
}
public static void NotifyBuildShipData(this Connection connection) {
connection.Send(new Sc12024());
Logger.c.Log("NotifyBuildShipData");
connection.Send(new Sc12024() {
WorklistCount = 1,
WorklistLists = BuildManager.Instance.ToBuildInfoes(),
DrawCount1 = 1,
DrawCount10 = 1,
ExchangeCount = 1,
});
}
}
}

View File

@@ -0,0 +1,149 @@
using BLHX.Server.Common.Proto.common;
using System;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using BLHX.Server.Common.Data;
using BLHX.Server.Common.Database;
using BLHX.Server.Common.Utils;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace BLHX.Server.Game.Managers {
public class BuildManager {
private static BuildManager instance = null;
private BuildManager() { }
public static BuildManager Instance {
get {
if (instance == null)
instance = new BuildManager();
return instance;
}
set => instance = value;
}
public uint BuildCapacity { get; set; } = 10;
public List<BuildData> BuildData { get; set; } = [];
public bool BuildShip(uint buildId) {
DateTime time = DateTime.Now;
DateTime finishTime = time.AddSeconds(10); // TODO: figure out which cfg is this stored at
if (BuildData.Count + 1 > BuildCapacity)
return false;
BuildData.Add(new BuildData() {
Pos = (uint)BuildData.Count + 1,
Tid = 1, // no idea whats this
BuildId = buildId,
FinishTime = (uint)new DateTimeOffset(finishTime).ToUnixTimeSeconds(),
Time = (uint)new DateTimeOffset(time).ToUnixTimeSeconds(),
});
return true;
}
public bool BatchBuildShip(uint buildId, uint count) {
if (BuildData.Count + count > BuildCapacity)
return false;
for (int i = 0; i < count; i++)
BuildShip(buildId);
return true;
}
public List<Shipinfo> GetBuildResults(List<uint> posList, uint playerUid) { // posList: build position list: so like 1, 2, 3, 4, 5
List<Shipinfo> buildResults = new List<Shipinfo>();
foreach (uint buildPosId in posList) {
BuildData buildData = BuildData[(int)buildPosId - 1];
Shipinfo receivedShip = CreateShipFromId(HandleGacha(buildData.BuildId), playerUid).ToProto();
buildResults.Add(receivedShip);
}
return buildResults;
}
public List<Shipinfo> GetAllBuildResults(uint playerUid) {
List<uint> posListAll = new List<uint>();
for (int i = 1; i <= BuildCapacity; i++)
posListAll.Add((uint)i);
return GetBuildResults(posListAll, playerUid);
}
public uint HandleGacha(uint bannerId) { // for now i changed the entire pool of bannerId = 2 to URs
uint[] characterPool = Data.ActivityShipCreate[bannerId].PickupList;
int resultRarity = RNG.NextShipRarity();
// handle gacha rates here
return characterPool[RNG.Next(characterPool.Length)];
}
// ayo who named these two :skull:
public List<BLHX.Server.Common.Proto.p12.BuildInfo> ToInfoLists() {
return BuildData.Select(data => new BLHX.Server.Common.Proto.p12.BuildInfo() { Pos = data.Pos, Tid = data.Tid }).ToList();
}
// this one is not capitalized Build(i)nfo
public List<BLHX.Server.Common.Proto.common.Buildinfo> ToBuildInfoes() {
return BuildData.Select(data => new BLHX.Server.Common.Proto.common.Buildinfo() { BuildId = data.BuildId, FinishTime = data.FinishTime, Time = data.Time,}).ToList();
}
public void ClearBuilds() {
BuildData.Clear();
}
public static ShipDataStatistics GetShipInfoFromId(uint shipId) {
return Data.ShipDataStatistics[(int)shipId];
}
public static PlayerShip CreateShipFromId(uint shipId, uint playerUid) {
if (!Data.ShipDataTemplate.TryGetValue((int)shipId, out var shipTemplate))
throw new InvalidDataException($"Ship template {shipId} not found!");
var ship = new PlayerShip() {
TemplateId = shipId,
Level = 1,
EquipInfoLists = [
new EquipskinInfo() { Id = shipTemplate.EquipId1 },
new EquipskinInfo() { Id = shipTemplate.EquipId2 },
new EquipskinInfo() { Id = shipTemplate.EquipId3 },
new EquipskinInfo(),
new EquipskinInfo(),
],
Energy = shipTemplate.Energy,
SkillIdLists = shipTemplate.BuffList.Select(x => new Shipskill() { SkillId = x, SkillLv = 1 }).ToList(),
Intimacy = 5000,
PlayerUid = playerUid
};
return ship;
}
}
[PrimaryKey(nameof(Pos))]
public class BuildData {
[Key]
public uint Pos { get; set; }
public uint Tid { get; set; }
public uint Time { get; set; }
public uint FinishTime { get; set; }
public uint BuildId { get; set; }
}
}