From 814eb5faec58301503497d6e7e305ce83956c667 Mon Sep 17 00:00:00 2001
From: "Mr. Stallion" <mrstallion@nobody.nowhere.fauxdomain.ext>
Date: Mon, 29 Jun 2020 14:30:08 -0500
Subject: [PATCH] Extra debug logging

---
 bbcode/parser.ts       |  6 ++--
 chat/Chat.vue          | 23 +++++++++++++++
 chat/ads/ad-manager.ts | 22 +++++++++++++++
 chat/conversations.ts  | 21 ++++++++++++++
 fchat/connection.ts    | 64 ++++++++++++++++++++++++++++++++++++++++--
 5 files changed, 130 insertions(+), 6 deletions(-)

diff --git a/bbcode/parser.ts b/bbcode/parser.ts
index 880d72b..d8bd799 100644
--- a/bbcode/parser.ts
+++ b/bbcode/parser.ts
@@ -145,19 +145,19 @@ export class BBCodeParser {
                     tagStart = i;
                     paramStart = -1;
                 } else {
-                    console.log('Hit depth tagOpen', depth);
+                    // console.log('Hit depth tagOpen', depth);
                 }
             } else if(c === '=' && paramStart === -1) {
                 if (depth <= 1) {
                   paramStart = i;
                 } else {
-                    console.log('Hit depth paramStart', depth);
+                    // console.log('Hit depth paramStart', depth);
                 }
             } else if(c === ']') {
                 depth--;
 
                 if (depth !== 0) {
-                    console.log('Hit depth tagClose', depth);
+                    // console.log('Hit depth tagClose', depth);
                 }
 
                 if (depth === 0) {
diff --git a/chat/Chat.vue b/chat/Chat.vue
index 61b2cd0..de5a916 100644
--- a/chat/Chat.vue
+++ b/chat/Chat.vue
@@ -33,6 +33,7 @@ import {InlineDisplayMode} from '../interfaces';
 </template>
 
 <script lang="ts">
+    import log from 'electron-log'; //tslint:disable-line:match-default-export-name
     import {Component, Hook, Prop} from '@f-list/vue-ts';
     import Vue from 'vue';
     import Modal from '../components/Modal.vue';
@@ -123,6 +124,17 @@ import {InlineDisplayMode} from '../interfaces';
                 }
             });
             core.connection.onEvent('closed', (isReconnect) => {
+                if(process.env.NODE_ENV !== 'production') {
+                    log.debug(
+                      {
+                        type: 'connection.closed',
+                        character: core.characters.ownCharacter?.name,
+                        error: this.error,
+                        isReconnect
+                      }
+                    );
+                }
+
                 if(isReconnect) (<Modal>this.$refs['reconnecting']).show(true);
                 if(this.connected) core.notifications.playSound('logout');
                 this.connected = false;
@@ -152,6 +164,17 @@ import {InlineDisplayMode} from '../interfaces';
                 document.title = (hasNew ? '💬 ' : '') + l(core.connection.isOpen ? 'title.connected' : 'title', core.connection.character);
             });
             core.connection.onError((e) => {
+
+                if(process.env.NODE_ENV !== 'production') {
+                    log.debug(
+                      {
+                        type: 'connection.error',
+                        error: errorToString(e),
+                        character: core.characters.ownCharacter?.name
+                      }
+                    );
+                }
+
                 if((<Error & {request?: object}>e).request !== undefined) {//catch axios network errors
                     this.error = l('login.connectError', errorToString(e));
                     this.connecting = false;
diff --git a/chat/ads/ad-manager.ts b/chat/ads/ad-manager.ts
index 3fb34fa..793309d 100644
--- a/chat/ads/ad-manager.ts
+++ b/chat/ads/ad-manager.ts
@@ -1,6 +1,8 @@
 import throat from 'throat';
 import * as _ from 'lodash';
 
+import log from 'electron-log'; //tslint:disable-line:match-default-export-name
+
 import core from '../core';
 import { Conversation } from '../interfaces';
 import Timer = NodeJS.Timer;
@@ -53,14 +55,34 @@ export class AdManager {
 
     // This makes sure there is a 5s delay between channel posts
     private async sendAdToChannel(msg: string, conv: Conversation.ChannelConversation): Promise<void> {
+        const initTime = Date.now();
+
         await adManagerThroat(
             async() => {
+                const throatTime = Date.now();
+
                 const delta = Date.now() - core.cache.getLastPost().getTime();
 
                 if ((delta > 0) && (delta < AdManager.POST_MANUAL_THRESHOLD)) {
                     await this.delay(delta);
                 }
 
+                const delayTime = Date.now();
+
+                if (process.env.NODE_ENV !== 'production') {
+                    log.debug(
+                      {
+                        type: 'sendAdToChannel',
+                        character: core.characters.ownCharacter?.name,
+                        channel: conv.channel.name,
+                        throatDelta: throatTime - initTime,
+                        delayDelta: delayTime - throatTime,
+                        totalWait: delayTime - initTime,
+                        msg
+                      }
+                    );
+                }
+
                 await conv.sendAd(msg);
             }
         );
diff --git a/chat/conversations.ts b/chat/conversations.ts
index 76cef6f..f339697 100644
--- a/chat/conversations.ts
+++ b/chat/conversations.ts
@@ -11,6 +11,7 @@ import MessageType = Interfaces.Message.Type;
 import {EventBus} from './preview/event-bus';
 import throat from 'throat';
 import Bluebird from 'bluebird';
+import log from 'electron-log'; //tslint:disable-line:match-default-export-name
 
 function createMessage(this: any, type: MessageType, sender: Character, text: string, time?: Date): Message {
     if(type === MessageType.Message && isAction(text)) {
@@ -395,13 +396,33 @@ class ChannelConversation extends Conversation implements Interfaces.ChannelConv
         if (text.length < 1)
             return;
 
+        const initTime = Date.now();
+
         await Conversation.conversationThroat(
             async() => {
+                const throatTime = Date.now();
+
                 await Conversation.testPostDelay();
 
+                const delayTime = Date.now();
+
                 core.connection.send('LRP', {channel: this.channel.id, message: text});
                 core.cache.markLastPostTime();
 
+                if (process.env.NODE_ENV !== 'production') {
+                    log.debug(
+                      {
+                        type: 'sendAd',
+                        character: core.characters.ownCharacter?.name,
+                        channel: this.channel.name,
+                        throatDelta: throatTime - initTime,
+                        delayDelta: delayTime - throatTime,
+                        totalWait: delayTime - initTime,
+                        text
+                      }
+                    );
+                }
+
                 await this.addMessage(
                     createMessage(MessageType.Ad, core.characters.ownCharacter, text, new Date())
                 );
diff --git a/fchat/connection.ts b/fchat/connection.ts
index 9f68890..b08869e 100644
--- a/fchat/connection.ts
+++ b/fchat/connection.ts
@@ -2,11 +2,15 @@ import Axios, {AxiosError, AxiosResponse} from 'axios';
 import * as qs from 'qs';
 import {Connection as Interfaces, WebSocketConnection} from './interfaces';
 import ReadyState = WebSocketConnection.ReadyState;
+import log from 'electron-log'; //tslint:disable-line:match-default-export-name
+import core from '../chat/core';
 
 const fatalErrors = [2, 3, 4, 9, 30, 31, 33, 39, 40, 62, -4];
 const dieErrors = [9, 30, 31, 39, 40];
 
 let lastFetch = Date.now();
+let lastApiTicketFetch = Date.now();
+
 
 async function queryApi(this: void, endpoint: string, data: object): Promise<AxiosResponse> {
     if (false) {
@@ -117,15 +121,41 @@ export default class Connection implements Interfaces.Connection {
 
     async queryApi<T = object>(endpoint: string, data?: {account?: string, ticket?: string}): Promise<T> {
         if(!this.ticketProvider) throw new Error('No credentials set!');
+
         if(data === undefined) data = {};
+
         data.account = this.account;
         data.ticket = this.ticket;
+
         let res = <T & {error: string}>(await queryApi(endpoint, data)).data;
+
         if(res.error === 'Invalid ticket.' || res.error === 'Your login ticket has expired (five minutes) or no ticket requested.') {
+            log.debug(
+              {
+                type: 'api.ticket.loss',
+                error: res.error,
+                character: core.characters.ownCharacter?.name,
+                deltaToLastApiCall: Date.now() - lastFetch,
+                deltaToLastApiTicket: Date.now() - lastApiTicketFetch
+              }
+            );
+
             data.ticket = this.ticket = await this.ticketProvider();
             res = <T & {error: string}>(await queryApi(endpoint, data)).data;
         }
+
         if(res.error !== '') {
+            log.debug(
+              {
+                type: 'error.api.query',
+                error: res.error,
+                endpoint,
+                character: core.characters.ownCharacter?.name,
+                deltaToLastApiCall: Date.now() - lastFetch,
+                deltaToLastApiTicket: Date.now() - lastApiTicketFetch
+              }
+            );
+
             const error = new Error(res.error);
             (<Error & {request: true}>error).request = true;
             throw error;
@@ -203,14 +233,42 @@ export default class Connection implements Interfaces.Connection {
     private async getTicket(password: string): Promise<string> {
         console.log('Acquiring new API ticket');
 
-        if (false) {
-            console.log(`https://www.f-list.net/json/getApiTicket.php, gap: ${Date.now() - lastFetch}ms`);
-            lastFetch = Date.now();
+        if(process.env.NODE_ENV !== 'production') {
+            console.log(`https://www.f-list.net/json/getApiTicket.php, gap: ${Date.now() - lastApiTicketFetch}ms`);
+
+            log.debug(
+              {
+                type: 'api.getTicket',
+                character: core.characters.ownCharacter?.name,
+                deltaToLastApiCall: Date.now() - lastFetch,
+                deltaToLastApiTicket: Date.now() - lastApiTicketFetch
+              }
+            );
+
+            lastApiTicketFetch = Date.now();
         }
 
         const data = <{ticket?: string, error: string}>(await Axios.post('https://www.f-list.net/json/getApiTicket.php', qs.stringify(
             {account: this.account, password, no_friends: true, no_bookmarks: true, no_characters: true}))).data;
+
         if(data.ticket !== undefined) return data.ticket;
+
+        if(process.env.NODE_ENV !== 'production') {
+            console.error('API Ticket Error', data.error);
+
+            log.error(
+              {
+                type: 'error.api.getTicket',
+                character: core.characters.ownCharacter.name,
+                error: data.error,
+                deltaToLastApiCall: Date.now() - lastFetch,
+                deltaToLastApiTicket: Date.now() - lastApiTicketFetch
+              }
+            );
+
+            lastApiTicketFetch = Date.now();
+        }
+
         throw new Error(data.error);
     }