[Server/Admin Tool][PC] Conan Exiles Chat Log Viewer


#1

Hello all, I’ve made a simple chat log viewer for a friend of mine and figured I could share it with you all here as well. Nothing fancy, pretty simple and straight forward. Written in AHK, doesn’t write/create files, just read-only. It read the ConanSandbox.log file and filters out the rest of the code. It has search functions, keywords, player name and by dates.

Here’s the compiled EXE for those who don’t have AHK installed.
https://www.dropbox.com/s/iscf2d4v4lhq695/Conan%20Exiles%20Chat%20Log%20Viewer.exe?dl=0

Here’s the AHK source code.

#NoEnv
SendMode Input
Global SelectedFile = ConanSandbox.log
Global DramaTemp = 
OnMessage(0x115, "OnScroll") ; WM_VSCROLL
OnMessage(0x114, "OnScroll") ; WM_HSCROLL

Menu, FileMenu, Add, &Open`tCtrl+O, MenuFileOpen  ; Created Open function with Ctrl+O as shortcut key.
Menu, FileMenu, Add, E&xit, MenuExit
Menu, HelpMenu, Add, &About, MenuAbout
Menu, HelpMenu, Add, &Instructions, MenuInstruc
Menu, MyMenuBar, Add, &File, :FileMenu  ; Attach the two sub-menus that were created above.
Menu, MyMenuBar, Add, &Help, :HelpMenu
Gui, Menu, MyMenuBar

Gui, Add, MonthCal, x610 y30 Multi AltSubmit 16 vMonth gMonthCal
Gui, Add, Edit, x610 y5 w185 h20 vSearch,
Gui, Add, Button, gSearchButton x795 y5 w40 h20, Search
Gui, Add, Button, gClearButton x610 y178 w225 h20, Clear Search Filter
Gui, Add, Edit, x5 y5 W600 H765 ReadOnly vDrama, Go to File > Open or Press Ctrl+O to open a log. ;%A_Index%
Gui, Add, ListView, Grid x610 y203 w225 h567 gPList AltSubmit vPlayerList, -  -  -  -  -   Player Name A to Z  -  -  -  -  -
Gui, Add, StatusBar,,Status: Ready!
Gui, Show, W840 H800 , Conan Exiles Chat Log Viewer
Gui, +LastFound ;Bring to focus
return

;==Player Search Function===============================

PList:
if(A_GuiEvent = "Normal")
{
	PLName := ""
	LV_GetText(PLName, A_EventInfo)
	if(!PLName)
	{
		GuiControl,,Drama, %DramaTemp%
		return
	}
	DramaPlayer := ""
	PLCount=0
	Loop, parse, DramaTemp, `n, `r  ;Reading chat log from memory instead of the log file, so we don't need to process that log again.
	{

		if(InStr(A_LoopField,PLName,true,23))
		{
			DramaPlayer=%DramaPlayer%%A_LoopField%`n
			PLCount++
		}
	}
	GuiControl,,Drama, %DramaPlayer%
	SB_SetText("Status: Searching chat log in loop is finished.")


}
SB_SetText("Status: Chat log truncation by player name completed. Found " . PLCount . " lines.")
return
;=================================


;==Date Search Function===============================
MonthCal:
SB_SetText("Status: Date selection detected and reading the dates.")
if(A_GuiEvent = "1")
{
GuiControlGet, Drama,
DramaDate := ""
DMCount=0
DateRange:= StrSplit(Month,"-")

;Creating two arrays for both start and end range by the year, month, and day.
DRStart:=[SubStr(DateRange[1],1,4),SubStr(DateRange[1],5,2),SubStr(DateRange[1],7,2)]
DREnd:=[SubStr(DateRange[2],1,4),SubStr(DateRange[2],5,2),SubStr(DateRange[2],7,2)]
SB_SetText("Status: Reading date by lines.")
Loop, parse, DramaTemp, `n, `r  
{
	DDTemp:= StrSplit(SubStr(A_LoopField,2,10),"/")
	
	if((DRStart[1] <= DDTemp[1]) and ( DREnd[1] >= DDTemp[1]))
	{
		if((DRStart[2] <= DDTemp[2]) and ( DREnd[2] >= DDTemp[2]))
		{
			if((DRStart[3] <= DDTemp[3]) and ( DREnd[3] >= DDTemp[3]))
			{
				DramaDate=%DramaDate%%A_LoopField%`n
				DMCount++
			}
		}
	}
}
GuiControl,,Drama, %DramaDate%
SB_SetText("Status: Chat log truncation by dates completed. Found " . DMCount . " lines.")
}
return
;===================================


;==Clear function=================================
ClearButton:
SB_SetText("Status: Clearing Search functions and restoring log")
LV_Modify(0, "-Select")
GuiControl,,Drama, %DramaTemp%
GuiControl,,Search,
GuiControl,,Month, %A_Now%
Sleep, 100 ;For some reason AHK get their OnMessage skipped if processed too fast. joy!
SB_SetText("Status: Cleared and Ready!")
return
;===================================


;==Search function=================================
SearchButton:
GuiControlGet, Search,
DramaSearch := ""
DSCount=0
Loop, parse, DramaTemp, `n, `r
	{

	if(InStr(A_LoopField,Search))
		{
		DramaSearch=%DramaSearch%%A_LoopField%`n
		DSCount++
		}
	}
GuiControl,,Drama, %DramaSearch%
SB_SetText("Status: Chat log truncation by keyword completed. Found " . DSCount . " lines.")
return
;===================================


;==Open Log into Memory===============================
LogRead(){
LV_Delete() ;Clear out any names if already written, happens when you open more than one during it's current session.
SB_SetText("Reading Log")
Loop, read, %SelectedFile%,
	{
		IfInString, A_LoopReadLine, ChatWindow: Character
		{
		CELOGYear := SubStr(A_LoopReadLine,2,4)
		CELOGMonth := SubStr(A_LoopReadLine,7,2)
		CELOGDay := SubStr(A_LoopReadLine,10,2)
		CELOGTime := SubStr(A_LoopReadLine,13,8) ;Capped to Hour/Min/Sec
		;CELOGTime := SubStr(A_LoopReadLine,13,12) ;Full Timestamp
		;CELOGCode := SubStr(A_LoopReadLine,27,3) ;Must figure this code out later on.
		
		CELOGNameEndPos := InStr(A_LoopReadLine,"said: ",true)-1
		CELOGName := SubStr(A_LoopReadLine,52,(CELOGNameEndPos)-52)
		RowNo:=LV_GetCount()
		;This loop checks if the name already exist in the list before adding current name to the list.
		Loop{
			if(RowNo=0)
			{
				LV_Insert(1,"",CELOGName)
				break
			}
			if(RowNo>=2)
			{
				LV_GetText(ExistingName,RowNo)
				if(ExistingName = CELOGName)
				{
					break
				}
				if(ExistingName != CELOGName)
				{
					RowNo--
				}
			}
			else if(RowNo=1)
			{
				LV_GetText(ExistingName,RowNo)
				if(ExistingName = CELOGName)
				{
					break
				}
				if(ExistingName != CELOGName)
				{
					LV_Insert(1,"",CELOGName)
					break
				}
			}
		}
		;MsgBox Debugging: %CELOGName% %ExistingName% %RowNo%
		CELOGMessage := SubStr(A_LoopReadLine,(CELOGNameEndPos+7))
		DramaLog = %DramaLog%[%CELOGYear%/%CELOGMonth%/%CELOGDay% %CELOGTime%] %CELOGName%: %CELOGMessage%`n
		}
}
GuiControl,,Drama, %DramaLog%
DramaTemp:=DramaLog
SB_SetText("Chat log reading: Finished")
return
}
;===================================


;==Open=================================
MenuFileOpen:
FileSelectFile, SelectedFile, 3, , Open a Conan Exiles Sandbox log file, Text Documents (*.log)
if SelectedFile =
{
return
}    
else{	
	LogRead()
	}
return
;===================================


;====Instruction===============================
MenuInstruc:
instruc := "This app is designed only to read the log file from Conan Exiles, nothing else.`n`nYou will need to find the log file from`n''Conan Exiles\ConanSandbox\Saved\Logs'' folder.`n`nOnce you located it, open the log through here via File>Open.`n`nYou can only use one of the search functions at a time.`n1: Keyword based search input.`n2: Range of date from the Calender`n3: Select one item from the list of player name.`n`nClicking on Clear Search Filter button will restore the log back to full result.`n`nThis app does not write anything into a file or the log, it's read-only. Does not save another file anywhere else.`n`n Enjoy rooting out the drama from your server! :D"
MsgBox, 64 ,Instructions,%instruc%,
return
;===================================


;====About Me!===============================
MenuAbout:
aboutinfo := "Conan Exiles Chat Log Viewer v1.0 (2018/6/16)`n`nWritten by Nacon 2018`n`nEmail: nacon@live.com`nDiscord: Nacon#1026`n`nCompiled in AutoHotKey"
MsgBox, 64 ,About,%aboutinfo%,
return
;===================================

;==Exit/Close Event=================================

MenuExit:
File.Close()
SB_SetText("Closing: Goodbye world!")
Sleep, 500 ;for the semi-quick readers
ExitApp
return

GuiClose:
File.Close()
SB_SetText("Closing: I am a leaf on the wind. Watch how I...")
Sleep, 20 ;for the super blazing fast readers
ExitApp
;===================================

Return

Please let me know if you found some issues or bugs with it.