-- Schema do emulador Rosh/Karos.
-- Aplicar com:  python aplicar_schema.py
-- Autenticacao: Windows (Trusted_Connection). Nenhuma senha fica em arquivo.

IF DB_ID('Rosh') IS NULL
    CREATE DATABASE Rosh;
GO

USE Rosh;
GO

-- Contas de login. O CLoginReqPacket (02 00) traz id e pw em texto claro do client, entao
-- guardamos a senha como hash SHA-256 com salt -- nunca o texto.
IF OBJECT_ID('dbo.conta', 'U') IS NULL
CREATE TABLE dbo.conta (
    conta_id        INT IDENTITY(1,1) PRIMARY KEY,
    usuario         NVARCHAR(64)  NOT NULL UNIQUE,
    senha_hash      CHAR(64)      NULL,      -- SHA-256 em hex; NULL = aceita qualquer senha
    senha_salt      CHAR(32)      NULL,
    bloqueada       BIT           NOT NULL DEFAULT 0,
    criada_em       DATETIME2     NOT NULL DEFAULT SYSUTCDATETIME(),
    ultimo_login_em DATETIME2     NULL,
    ultimo_ip       VARCHAR(45)   NULL
);
GO

-- Personagens. entity_id e o id que anda nos pacotes do jogo (10654 no personagem capturado).
IF OBJECT_ID('dbo.personagem', 'U') IS NULL
CREATE TABLE dbo.personagem (
    personagem_id INT IDENTITY(1,1) PRIMARY KEY,
    conta_id      INT           NOT NULL REFERENCES dbo.conta(conta_id),
    entity_id     INT           NOT NULL UNIQUE,
    nome          NVARCHAR(64)  NOT NULL,
    classe        INT           NOT NULL DEFAULT 500,
    aparencia     INT           NOT NULL DEFAULT 0,
    nivel         INT           NOT NULL DEFAULT 1,
    exp           INT           NOT NULL DEFAULT 0,
    hp            INT           NOT NULL DEFAULT 186,
    hp_max        INT           NOT NULL DEFAULT 186,
    mp            INT           NOT NULL DEFAULT 100,
    mp_max        INT           NOT NULL DEFAULT 100,
    -- campos do 08 01 ainda sem identificacao, mas que mudam no level up / por abate.
    -- Guardados para o pacote sair identico ao do servidor real. Ver docs/findings.md.
    campo43       INT           NOT NULL DEFAULT 2,
    contador45    INT           NOT NULL DEFAULT 0,
    contador54    INT           NOT NULL DEFAULT 0,
    pos_x         REAL          NULL,
    pos_y         REAL          NULL,
    pos_z         REAL          NULL,
    criado_em     DATETIME2     NOT NULL DEFAULT SYSUTCDATETIME(),
    atualizado_em DATETIME2     NOT NULL DEFAULT SYSUTCDATETIME()
);
GO

CREATE OR ALTER PROCEDURE dbo.salvar_progresso
    @entity_id  INT,
    @nivel      INT,
    @exp        INT,
    @hp         INT,
    @hp_max     INT,
    @mp         INT,
    @mp_max     INT,
    @campo43    INT,
    @contador45 INT,
    @contador54 INT
AS
BEGIN
    SET NOCOUNT ON;
    UPDATE dbo.personagem
       SET nivel = @nivel, exp = @exp,
           hp = @hp, hp_max = @hp_max, mp = @mp, mp_max = @mp_max,
           campo43 = @campo43, contador45 = @contador45, contador54 = @contador54,
           atualizado_em = SYSUTCDATETIME()
     WHERE entity_id = @entity_id;
END
GO
