OkMuOnline


NowaHosting


AlphaServers


Resultados 1 a 2 de 2
  1. #1
    Membro cronusmaker's Avatar

    Data de Ingresso
    Dec 2022
    Posts
    20
    Thanks Thanks Given 
    21
    Thanks Thanks Received 
    30
    Thanked in
    9 Posts
    Mentioned
    0 Post(s)
    Humor
    Cheerful
    País
    Brazil

    Contagem de tempo online de conta + char (HOT)

    Atenção
    funciona melhor em sql 2008+



    Há tempos vejo pessoas pedindo query pra contar tempo online de char, então resolvi por a mão na massa e fazer uma.


    Se houver bugs eu fixo, só avisar aqui, mas aparentemente está 100% (fiz inúmeros testes).[B]


    A contagem é feita em segundos e é armazenada:


    - Tempo da conta: na MEMB_INFO, coluna TimeON.
    - Tempo de cada char: na Character, coluna TimeON.




    O tempo online é atualizado:


    - Quando você seleciona char (mesmo se não trocar de char).
    - Quando você troca de char.
    - Quando você desloga a conta.


    Vamos lá.




    [B]♦ Versões atuais dos Scripts:


    - TRIGGER: 2.1.2
    - WZ_DISCONNECT_MEMB: 2.0.0




    [B]♦ ALTER TABLES
    Código PHP:
    USE [MUOnline]GO
    ALTER TABLE 
    [dbo].[MEMB_STAT]ALTER COLUMN [ConnectTM] [datetimeNULLGO
    ALTER TABLE 
    [dbo].[MEMB_STAT]ALTER COLUMN [DisConnectTM] [datetimeNULLGO
    ALTER TABLE 
    [dbo].[MEMB_INFO]ADD    [TimeON] [bigintNOT NULL DEFAULT 0GO
    ALTER TABLE 
    [dbo].[Character]ADD    [ConnectTM] [datetimeNULLGO
    ALTER TABLE 
    [dbo].[Character]ADD    [DisConnectTM] [datetimeNULLGO
    ALTER TABLE  
    [dbo].[Character]ADD    [TimeON] [bigint] DEFAULT ((0)) NOT NULLGO 

    ♦ TRIGGER - AccountCharacter_Online


    Código PHP:
    /*| @author - Renato Valer| @version - 2.1.2| @last update - 2016/02/12 - 08h18min| @warning: Não me responsabilizo por uso incorreto e possíveis deadlocks. Use por sua conta e risco.*/
    USE MuOnlineGO
    IF EXISTS (SELECT name FROM sysobjects WHERE name 'AccountCharacter_Online' AND type 'TR')    DROP TRIGGER [AccountCharacter_Online]GO
    CREATE TRIGGER 
    [AccountCharacter_OnlineON [dbo].[AccountCharacterAFTER UPDATE AS    SET NOCOUNT ON
    /*|    Hipóteses|    ||        1 - Se GameIDC foi atualizado, algum char foi foi logado. Surgem hipóteses:||            1.1 - GameIDC e Old_GameIDC são diferentes:|    |                1.1.1 - Old_GameIDC é NULL, logo é o primeiro char logado (e possivelmente o primeiro criado) na conta, |                    pois não existe GameIDC anterior.|                1.1.2 - Já existe um GameIDC anterior, logo significa que o cara acessou outro char. Surgem 2 hipóteses:||                    1.1.2.1 - O cara simplesmente trocou de char sem deslogar a conta:|                        1.1.2.1.1 - O cara logou um char, deletou ele e entrou em outro.|                    1.1.2.2 - O cara relogou a conta e entrou em outro char.|                        1.1.2.2.1 - O cara logou um char, deletou ele, saiu da conta, voltou e entrou em outro.|                        |            1.2 GameIDC e Old_GameIDC são iguais:|                        |                1.2.1 - O cara relogou o char.|                1.2.2 - O cara relogou a conta e entrou no mesmo char.||        2. Se GameIDC não foi atualizado, não precisa fazer nada, porque significa:|        |            2.1 - Que um char foi criado, mas não foi logado.|            2.2 - Que um char foi deletado sem nem mesmo ter sido logado.|                |        */
    -- Hipótese 1IF UPDATE(GameIDCBEGIN
        
    DECLARE @Login VARCHAR(10),    @GameIDC VARCHAR(10),    @Old_GameIDC VARCHAR(10),    @GameIDC_ConnectTM DATETIME,    @GameIDC_ConnectTM_Int INT,    @Old_GameIDC_ConnectTM DATETIME,    @Old_GameIDC_ConnectTM_Int INT,    @GameIDC_DisConnectTM DATETIME,    @GameIDC_DisConnectTM_Int INT,    @Old_GameIDC_DisConnectTM DATETIME,    @Old_GameIDC_DisConnectTM_Int INT,    @account_DisconnectTM DATETIME,    @account_DisconnectTM_Int INT,    @Now DATETIME,    @Now_Int INT,    @TimeON BIGINT;
        
    SET @Login = (SELECT Id FROM INSERTED);    SET @GameIDC = (SELECT GameIDC FROM AccountCharacter WHERE Id = @Login);    SET @Old_GameIDC = (SELECT GameIDC FROM DELETED);    SET @Now GETDATE();    SET @Now_Int DATEDIFF(s'19700101', @Now);    SET @account_DisconnectTM = (SELECT DisconnectTM FROM MEMB_STAT WHERE memb___id = @Login);    SET @account_DisconnectTM_Int DATEDIFF(s'19700101', @account_DisconnectTM);
        -- 
    Hipótese 1.1    IF(@GameIDC <> @Old_GameIDCBEGIN
            
    -- Hipótese 1.1.1        IF(@Old_GameIDC IS NULLBEGIN                        UPDATE Character SET ConnectTM = @Now WHERE AccountID = @Login AND Name = @GameIDC;                    END        -- Hipótese 1.1.2        ELSE BEGIN                    SET @Old_GameIDC_DisconnectTM = @Now            SET @Old_GameIDC_DisconnectTM_Int = @Now_Int;                        -- Hipótese 1.1.2.1            IF @account_DisconnectTM_Int <> @Old_GameIDC_DisconnectTM_IntBEGIN                            -- Verificação da Hipótese 1.1.2.1.1                IF EXISTS(SELECT Name FROM Character WHERE AccountID = @Login AND Name = @Old_GameIDCBEGIN
                        SET 
    @Old_GameIDC_ConnectTM = (SELECT ConnectTM FROM Character WHERE AccountID = @Login AND Name = @Old_GameIDC);                    SET @Old_GameIDC_ConnectTM_Int DATEDIFF(s'19700101', @Old_GameIDC_ConnectTM);                                SET @TimeON = @Old_GameIDC_DisconnectTM_Int - @Old_GameIDC_ConnectTM_Int;                                    UPDATE Character SET TimeON TimeON + @TimeONDisConnectTM = @Now WHERE AccountID = @Login AND Name = @Old_GameIDC;                                                    END                            END            -- Hipótese 1.1.2.2 e "fim" da Hipótese 1.1.2.1            -- A query é a mesma e um "else" é desnecessário.                    /*            |    Não é necessário atualizar tempo on, porque se o cara relogou a conta            |    a WZ_DISCONNECT_MEMB já fez o serviço. Só precisamos atualizar o momento            |    de connect do novo char.            */            UPDATE Character SET ConnectTM = @Now WHERE AccountID = @Login AND Name = @GameIDC;                                    END            END    --Hipótese 1.2.    ELSE BEGIN        -- Apenas precaução...        IF(@GameIDC IS NOT NULLBEGIN                        /*            |    Desnecessário checar se o char existe, porque se essa parte             |    do script está sendo executada, é porque o char foi logado            |    agora, logo é presumível que existe.            */                        SET @GameIDC_ConnectTM = (SELECT ConnectTM FROM Character WHERE AccountID = @Login AND Name = @GameIDC);            SET @GameIDC_ConnectTM_Int DATEDIFF(s'19700101', @GameIDC_ConnectTM);            SET @GameIDC_DisconnectTM_Int = @Now_Int;
                -- 
    Hipótese 1.2.1            IF @account_DisconnectTM_Int < @GameIDC_ConnectTM_IntBEGIN                                SET @TimeON = @GameIDC_DisconnectTM_Int - @GameIDC_ConnectTM_Int;                UPDATE Character SET TimeON TimeON + @TimeONDisConnectTM = @NowConnectTM = @Now WHERE AccountID = @Login AND Name = @GameIDC;                            END            -- Hipótese 1.2.2            ELSE BEGIN                /*                    Não é necessário atualizar tempo on, porque se o cara relogou a conta                    a WZ_DISCONNECT_MEMB já fez o serviço.                */                UPDATE Character SET ConnectTM = @Now WHERE AccountID = @Login AND Name = @GameIDC;                            END                        END            END    SET NOCOUNT OFFEND 

    ♦ PROCEDURE WZ_DISCONNECT_MEMB


    Código PHP:
    /*| @modifications - Renato Valer| @version - 2.0.0| @last update - 2015/08/28 - 09h25min| @warning: Não me responsabilizo por uso incorreto e possíveis deadlocks. Use por sua conta e risco.*/
    USE MuOnlineGO
    IF EXISTS (SELECT FROM sys.objects WHERE type 'P' AND name 'WZ_DISCONNECT_MEMB')DROP PROCEDURE [DBO].[WZ_DISCONNECT_MEMB]GO
    CREATE PROCEDURE 
    [DBO].[WZ_DISCONNECT_MEMB] @memb___id VARCHAR(10) AS BEGIN
    SET NOCOUNT ON
    DECLARE @Find_ID VARCHAR(10),@ConnectStat TINYINT,@LoginTime INT,@LogoutTime INT,@ConnectTM INT,@DisConnectTM INT,@TimeON_Account BIGINT,@TimeON_Char BIGINT,@GameIDC VARCHAR(10),@CharConnectTM DATETIME,@CharConnectTM_Int INT,@Now DATETIME,@Now_Int INT;
    SET @ConnectStat 0SET @Find_ID 'NOT'SET @Now GETDATE();
    SELECT @Find_ID S.memb___id FROM MEMB_STAT S INNER JOIN MEMB_INFO I ON S.memb___id COLLATE DATABASE_DEFAULT I.memb___id WHERE I.memb___id = @memb___id;
    IF( @
    Find_ID <> 'NOT' BEGIN    
    UPDATE MEMB_STAT SET ConnectStat 
    = @ConnectStatDisconnectTM = @Now WHERE memb___id = @memb___id;

    /*Selecionamos os momentos de login e logout da conta e convertemos para números inteiros.*/
    SET @ConnectTM = (SELECT DATEDIFF(s'19700101'MEMB_STAT.ConnectTMFROM MEMB_STAT WHERE memb___id = @memb___id);SET @DisConnectTM DATEDIFF(s'19700101', @Now);

    /*Executamos os cálculos para obtermos o tempo total online da conta.*/
    SET @TimeON_Account = @DisConnectTM - @ConnectTM;
    /*Atualizamos o tempo total online da conta.*/
    UPDATE MEMB_INFO SET TimeON TimeON + @TimeON_Account WHERE memb___id = @memb___id;

    /*Selecionando nick do último char logado*/    
    SET @GameIDC = (SELECT GameIDC FROM AccountCharacter WHERE Id = @memb___id);
    /*Algum char foi logado antes de sair da conta.Mesmo que o cara tenha logado na conta e criado o char, o GameIDCsó vai ser preenchido se o cara logar na conta.Sendo assim, se GameIDC for NULL, indica que nenhum charnunca foi logado nessa conta, então não tem necessidade de contar tempo on.*/    IF(@GameIDC IS NOT NULLBEGIN
    /*Verificamos se esse char existe.Motivo: o cara pode ter clicado em "selecionar char", deletado o char e depois deslogado da conta.Se não existe, não precisa fazer nada.*/IF EXISTS (SELECT Name FROM Character WHERE AccountID = @memb___id AND Name = @GameIDCBEGIN
    /*Verificação: quando foi o último connect desse char que acabou de deslogar?Se for nulo, significa que ocorreu algum problema na trigger, entãoadicionamos o valor de "agora" convertido em timestamp para possibilitar o cálculo.*/
    SET @CharConnectTM = (SELECT ConnectTM FROM Character WHERE AccountID = @memb___id AND Name = @GameIDC);IF (@CharConnectTM IS NULLBEGINSET @CharConnectTM_Int DATEDIFF(s'19700101', @Now);END/*Se não for nulo, convertemos para timestamp.*/ELSE BEGINSET @CharConnectTM_Int DATEDIFF(s'19700101', @CharConnectTM);END
    /*Executamos os cálculos para obtermos o tempo total onlinedo último char logado.*/
    SET @TimeON_Char = (@DisConnectTM - @CharConnectTM_Int);
    /*Atualizamos o tempo total online do último char logado.*/
    UPDATE Character SET TimeON TimeON + @TimeON_CharDisConnectTM = @Now WHERE AccountID = @memb___id AND Name = @GameIDC;    
    ENDENDENDSET NOCOUNT OFFEND 



    Atenção

    ATENÇÃO




    Não me responsabilizo por uso incorreto.
    Não me responsabilizo por eventuais deadlocks. Usem por conta e risco.


    Agradecimentos a @navossoc, @Willerson, @Erick-Master e @viOleNt pela colaboração.


    []'s



    Creditos Renato ( Imperyus )

  2. #2
    Iniciante AnDeR's Avatar

    Data de Ingresso
    Jul 2022
    Posts
    5
    Thanks Thanks Given 
    68
    Thanks Thanks Received 
    1
    Thanked in
    1 Post
    Mentioned
    0 Post(s)
    País
    Brazil
    aqui deu erro

    Msg 102, Level 15, State 1, Procedure AccountCharacter_Online, Line 80
    Incorrect syntax near ')'.
    Msg 102, Level 15, State 1, Procedure AccountCharacter_Online, Line 123
    Incorrect syntax near ')'.
    Msg 156, Level 15, State 1, Procedure AccountCharacter_Online, Line 130
    Incorrect syntax near the keyword 'ELSE'.

Permissões de Postagem

  • Você não pode iniciar novos tópicos
  • You may not post Resposta(s)
  • Você não pode enviar anexos
  • Você não pode editar suas mensagens
  •