Resultados 1 a 10 de 15

Hybrid View

  1. #1
    Developer C++ s00x's Avatar

    Data de Ingresso
    Jan 2015
    Posts
    373
    Thanks Thanks Given 
    75
    Thanks Thanks Received 
    146
    Thanked in
    24 Posts
    Mencionado
    63 Post(s)
    MEU HUMOR
    Cheerful
    País
    United States
    Citação Originally Posted by itechcoomputers Ver Post
    Cara me salvo, agora queria saber porque no meu servidor tem as tabelas de horas online e elas não contabilizam sempre fica 0 "zero" ?
    Então meu Jovem, vamos la:

    Tabelas a serem criadas:
    Código:
    USE [MUOnline]
    GO
    
    ALTER TABLE [dbo].[MEMB_STAT]
    ALTER COLUMN [ConnectTM] [datetime] NULL
    GO
    
    ALTER TABLE [dbo].[MEMB_STAT]
    ALTER COLUMN [DisConnectTM] [datetime] NULL
    GO
    
    ALTER TABLE [dbo].[MEMB_INFO]
    ADD	[TimeON] [bigint] NOT NULL DEFAULT 0
    GO
    
    ALTER TABLE [dbo].[Character]
    ADD	[ConnectTM] [datetime] NULL
    GO
    
    ALTER TABLE [dbo].[Character]
    ADD	[DisConnectTM] [datetime] NULL
    GO
    
    ALTER TABLE  [dbo].[Character]
    ADD	[TimeON] [bigint] DEFAULT ((0)) NOT NULL
    GO
    Cria essa Trigger
    Código:
    /*
    | @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 MuOnline
    GO
    
    IF EXISTS (SELECT name FROM sysobjects WHERE name = 'AccountCharacter_Online' AND type = 'TR')
        DROP TRIGGER [AccountCharacter_Online]
    GO
    
    CREATE TRIGGER [AccountCharacter_Online] ON [dbo].[AccountCharacter] 
    AFTER 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 1
    IF UPDATE(GameIDC) BEGIN
    
        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_GameIDC) BEGIN
    
            -- Hipótese 1.1.1
            IF(@Old_GameIDC IS NULL) BEGIN
                
                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_Int) BEGIN
                
                    -- Verificação da Hipótese 1.1.2.1.1
                    IF EXISTS(SELECT Name FROM Character WHERE AccountID = @Login AND Name = @Old_GameIDC) BEGIN
    
                        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 + @TimeON, DisConnectTM = @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 NULL) BEGIN
                
                /*
                |    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_Int) BEGIN
                    
                    SET @TimeON = @GameIDC_DisconnectTM_Int - @GameIDC_ConnectTM_Int;
                    UPDATE Character SET TimeON = TimeON + @TimeON, DisConnectTM = @Now, ConnectTM = @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 OFF
    END
    Agora vamos criar a Procedure:
    Código:
    /*
    | @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 MuOnline
    GO
    
    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 = 0
    SET @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 = @ConnectStat, DisconnectTM = @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.ConnectTM) FROM 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 GameIDC
    só vai ser preenchido se o cara logar na conta.
    Sendo assim, se GameIDC for NULL, indica que nenhum char
    nunca foi logado nessa conta, então não tem necessidade de contar tempo on.
    */	
    IF(@GameIDC IS NOT NULL) BEGIN
    
    /*
    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 = @GameIDC) BEGIN
    
    /*
    Verificação: quando foi o último connect desse char que acabou de deslogar?
    Se for nulo, significa que ocorreu algum problema na trigger, então
    adicionamos 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 NULL) BEGIN
    SET @CharConnectTM_Int = DATEDIFF(s, '19700101', @Now);
    END
    /*
    Se não for nulo, convertemos para timestamp.
    */
    ELSE BEGIN
    SET @CharConnectTM_Int = DATEDIFF(s, '19700101', @CharConnectTM);
    END
    
    /*
    Executamos os cálculos para obtermos o tempo total online
    do último char logado.
    */
    
    SET @TimeON_Char = (@DisConnectTM - @CharConnectTM_Int);
    
    /*
    Atualizamos o tempo total online do último char logado.
    */
    
    UPDATE Character SET TimeON = TimeON + @TimeON_Char, DisConnectTM = @Now WHERE AccountID = @memb___id AND Name = @GameIDC;	
    
    END
    END
    END
    SET NOCOUNT OFF
    END
    Caso queira informar isso no seu WebSite:
    Código PHP:
    <?php
    $find 
    mssql_query("SELECT TimeON FROM MEMB_INFO WHERE memb___id='".$login."'");
    $fetch mssql_fetch_object($find);    
    $seconds $fetch->TimeON;
    $hours floor($seconds 3600);
    $seconds -= $hours 3600;
    $minutes floor($seconds 60);
    $seconds -= $minutes 60;
    $timeON = (''.$hours.'h'.$minutes.'min'.$seconds.'sec');
    echo 
    $timeON;
    ?>
    Esse código está exibindo as horas online da Conta, caso queira exibir as horas online do Char, recomendo utilizar isso:
    Código PHP:
    $find mssql_query("SELECT TimeON FROM MEMB_INFO WHERE memb___id='".$name."'"); 
    Esse código/procedimento está perfeito, é até burrice tentar criar algo semelhante com isso já pronto.
    Meu jovem, caso tenha feito algum procedimento para contabilizar as horas, recomendo você remover antes de executar esses procedimentos.

    Recomendações Mínimas: Microsoft SQL Server 2008 R2

    Créditos
    Renato Valer
    Last edited by s00x; 29/03/2017 at 05:25 PM.
    É melhor estar enganado, do que ser enganado.

  2. #2
    Membro iTechTeam's Avatar
    Data de Ingresso
    Mar 2017
    Posts
    134
    Thanks Thanks Given 
    21
    Thanks Thanks Received 
    1
    Thanked in
    1 Post
    Mencionado
    9 Post(s)
    MEU HUMOR
    In Love
    País
    Brazil
    Apenas agradeço o conhecimento passado agora funcionou obrigado @[Somente membros podem ver os links. ] ,sempre passando conhecimento e disposto ajudar ! #ComunidadeEvoluindo
    iTechTeam ®

Tags para este Tópico

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
  •  
Sobre nós
Somos uma comunidade em atividade a 8 anos que aborda assuntos relacionados a games em geral, principalmente games MMORPG. e que busca sempre ajudar os membros através de conteúdos, tutoriais e suporte...
Nossos anunciantes
Hinetworks
VelozHost
InovHost
Rede Sociais