Skip to content

Commit

Permalink
Fixed handler unregistration bug
Browse files Browse the repository at this point in the history
+ Renamed MyPathIsWrongEvent to MyPathIsUnsupportedEvent
+ Fixed the bug 'when changing server, previous handlers are not unregistered and previous handler watchdog threads are not terminated'
  • Loading branch information
hsheric0210 committed Apr 9, 2022
1 parent 4761bc5 commit abadb4c
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 84 deletions.
Binary file modified .vs/AutoKkutu/v17/.suo
Binary file not shown.
148 changes: 84 additions & 64 deletions Handlers/CommonHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
using CefSharp;
using CefSharp.Wpf;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Threading;

namespace AutoKkutu
{
Expand All @@ -22,27 +24,27 @@ public abstract class CommonHandler

private Task _watchdogTask;

private CancellationTokenSource cancelTokenSrc;
private readonly int _checkgame_interval = 3000;
private readonly int _ingame_interval = 1;
private bool _isgamestarted = false;
private bool _isMyTurn = false;
private bool _isWatchdogStarted = false;
private volatile bool _isWatchdogAlive = true;
private string _current_mission_word = "";
private string _wordCache = "";
private string _roundCache = "";
private string _unsupportedWordCache = "";
private string _exampleWordCache = "";

public EventHandler GameStartedEvent;
public EventHandler GameEndedEvent;
public EventHandler MyTurnEvent;
public EventHandler MyTurnEndedEvent;
public EventHandler RoundEndedEvent;
public EventHandler PastDictionaryEvent;
public EventHandler WrongWordEvent;
public EventHandler MyPathIsWrongEvent;
public EventHandler RoundChangeEvent;
public event EventHandler onGameStarted;
public event EventHandler onGameEnded;
public event EventHandler<MyTurnEventArgs> onMyTurn;
public event EventHandler onMyTurnEnded;
//public event EventHandler onRoundEnded;
//public event EventHandler onPastDictionary;
public event EventHandler<UnsupportedWordEventArgs> onUnsupportedWordEntered;
public event EventHandler<UnsupportedWordEventArgs> onMyPathIsUnsupported;
public event EventHandler onRoundChange;

public enum CheckType
{
Expand All @@ -61,9 +63,10 @@ public static void InitHandlers(ChromiumWebBrowser browser)

public static CommonHandler getHandler(string url)
{
foreach (CommonHandler handler in HANDLERS)
if (Regex.Match(url, handler.GetSiteURLPattern()).Success)
return handler;
if (!string.IsNullOrEmpty(url))
foreach (CommonHandler handler in HANDLERS)
if (Regex.Match(url, handler.GetSiteURLPattern()).Success)
return handler;
return null;
}

Expand All @@ -73,40 +76,53 @@ public void StartWatchdog()
{
if (!_isWatchdogStarted)
{
_isWatchdogAlive = true;
_isWatchdogStarted = true;
_watchdogTask = new Task(Watchdog);
cancelTokenSrc = new CancellationTokenSource();
_watchdogTask = new Task(() => Watchdog(cancelTokenSrc.Token), cancelTokenSrc.Token);
_watchdogTask.Start();
Log(ConsoleManager.LogType.Info, "Watchdog thread started.");
Log(ConsoleManager.LogType.Info, "Watchdog thread started.", CurrentWatchdogID);
}
}
public void StopWatchdog()
{
if (_isWatchdogStarted)
{
Log(ConsoleManager.LogType.Info, "Watchdog thread stop requested.", CurrentWatchdogID);
cancelTokenSrc?.Cancel();
_isWatchdogStarted = false;
_isWatchdogAlive = false;
Log(ConsoleManager.LogType.Info, "Watchdog thread stop requested.");
}
}

private async void Watchdog()
private async void Watchdog(CancellationToken cancelToken)
{
while (_isWatchdogAlive)
int watchdogID = CurrentWatchdogID;
try
{
CheckGameState(CheckType.GameStarted);
if (_isgamestarted)
cancelToken.ThrowIfCancellationRequested();

while (true)
{
CheckGameState(CheckType.MyTurn);
GetPreviousWord();
GetCurrentRound();
GetCurrentMissionWord();
CheckUnsupportedWord();
CheckExample();
await Task.Delay(_ingame_interval);
if (cancelToken.IsCancellationRequested)
cancelToken.ThrowIfCancellationRequested();

CheckGameState(CheckType.GameStarted, watchdogID);
if (_isgamestarted)
{
CheckGameState(CheckType.MyTurn, watchdogID);
GetPreviousWord(watchdogID);
GetCurrentRound(watchdogID);
GetCurrentMissionWord(watchdogID);
CheckUnsupportedWord(watchdogID);
CheckExample(watchdogID);
await Task.Delay(_ingame_interval, cancelToken);
}
else
await Task.Delay(_checkgame_interval, cancelToken);
}
else
await Task.Delay(_checkgame_interval);
}
catch (Exception ex)
{
Log(ConsoleManager.LogType.Info, $"Watchdog thread terminated: {ex}.", watchdogID);
}
}

Expand All @@ -122,92 +138,92 @@ protected string EvaluateJS(string javaScript)
}
catch (Exception ex)
{
Log(ConsoleManager.LogType.Error, "Failed to run script on site. Expection : \n" + ex.ToString());
Log(ConsoleManager.LogType.Error, "Failed to run script on site. Expection : \n" + ex.ToString(), CurrentWatchdogID);
return " ";
}
}

private void CheckGameState(CheckType type)
private void CheckGameState(CheckType type, int watchdogID)
{
if (type == CheckType.GameStarted ? IsGameNotInProgress() : IsGameNotInMyTurn())
{
if (type == CheckType.GameStarted)
{
if (!IsGameStarted)
return;
Log(ConsoleManager.LogType.Info, "Game ended.");
if (GameEndedEvent != null)
GameEndedEvent(this, EventArgs.Empty);
Log(ConsoleManager.LogType.Info, "Game ended.", watchdogID);
if (onGameEnded != null)
onGameEnded(this, EventArgs.Empty);
_isgamestarted = false;
}
else if (IsMyTurn)
{
Log(ConsoleManager.LogType.Info, "My turn ended.");
if (MyTurnEndedEvent != null)
MyTurnEndedEvent(this, EventArgs.Empty);
Log(ConsoleManager.LogType.Info, "My turn ended.", watchdogID);
if (onMyTurnEnded != null)
onMyTurnEnded(this, EventArgs.Empty);
_isMyTurn = false;
}
}
else if (type == CheckType.GameStarted)
{
if (_isgamestarted)
return;
Log(ConsoleManager.LogType.Info, "New round started; Previous word list flushed.");
if (GameStartedEvent != null)
GameStartedEvent(this, EventArgs.Empty);
Log(ConsoleManager.LogType.Info, "New round started; Previous word list flushed.", watchdogID);
if (onGameStarted != null)
onGameStarted(this, EventArgs.Empty);
_isgamestarted = true;
}
else if (!_isMyTurn)
{
ResponsePresentedWord presentedWord = GetPresentedWord();
if (presentedWord.CanSubstitution)
Log(ConsoleManager.LogType.Info, $"My Turn. presented word is {presentedWord.Content} (Subsitution: {presentedWord.Substitution})");
Log(ConsoleManager.LogType.Info, $"My Turn. presented word is {presentedWord.Content} (Subsitution: {presentedWord.Substitution})", watchdogID);
else
Log(ConsoleManager.LogType.Info, $"My Turn. presented word is {presentedWord.Content}");
Log(ConsoleManager.LogType.Info, $"My Turn. presented word is {presentedWord.Content}", watchdogID);
CurrentPresentedWord = presentedWord;
if (MyTurnEvent != null)
MyTurnEvent(this, new MyTurnEventArgs(presentedWord, CurrentMissionChar));
if (onMyTurn != null)
onMyTurn(this, new MyTurnEventArgs(presentedWord, CurrentMissionChar));
_isMyTurn = true;
}
}

private void GetPreviousWord()
private void GetPreviousWord(int watchdogID)
{
string previousWord = GetGamePreviousWord();
if (string.IsNullOrWhiteSpace(previousWord))
return;
string word = previousWord.Split('<')[0];
if (word == _wordCache)
return;
Log(ConsoleManager.LogType.Info, "Found Previous Word : " + word);
Log(ConsoleManager.LogType.Info, "Found Previous Word : " + word, watchdogID);
_wordCache = word;
if (word != MainWindow.LastUsedPath && !PathFinder.NewPathList.Contains(word))
PathFinder.NewPathList.Add(word);
PathFinder.AddPreviousPath(word);
}

private void GetCurrentMissionWord()
private void GetCurrentMissionWord(int watchdogID)
{
string missionWord = GetMissionWord();
if (string.IsNullOrWhiteSpace(missionWord) || string.Equals(missionWord, _current_mission_word, StringComparison.InvariantCulture))
return;
Log(ConsoleManager.LogType.Info, "Mission Word Changed: " + missionWord);
Log(ConsoleManager.LogType.Info, "Mission Word Changed: " + missionWord, watchdogID);
_current_mission_word = missionWord;
}

private void GetCurrentRound()
private void GetCurrentRound(int watchdogID)
{
string round = GetGameRound();
if (string.IsNullOrWhiteSpace(round) || string.Equals(round, _roundCache, StringComparison.InvariantCulture))
return;
Log(ConsoleManager.LogType.Info, "Round Changed: " + round);
if (RoundChangeEvent != null)
RoundChangeEvent(this, EventArgs.Empty);
Log(ConsoleManager.LogType.Info, "Round Changed: " + round, watchdogID);
if (onRoundChange != null)
onRoundChange(this, EventArgs.Empty);
PathFinder.PreviousPath = new List<string>();
_roundCache = round;
}

private void CheckUnsupportedWord()
private void CheckUnsupportedWord(int watchdogID)
{
string unsupportedWord = GetUnsupportedWord();
if (string.IsNullOrWhiteSpace(unsupportedWord) || string.Equals(unsupportedWord, _unsupportedWordCache, StringComparison.InvariantCultureIgnoreCase) || unsupportedWord.Contains("T.T"))
Expand All @@ -216,25 +232,27 @@ private void CheckUnsupportedWord()
bool isExistingWord = unsupportedWord.Contains(":"); // 첫 턴 한방 금지, 한방 단어(매너) 등등...
_unsupportedWordCache = unsupportedWord;

if (WrongWordEvent != null)
WrongWordEvent(this, new WrongWordEventArgs(unsupportedWord, isExistingWord));
if (IsMyTurn && MyPathIsWrongEvent != null)
MyPathIsWrongEvent(this, new WrongWordEventArgs(unsupportedWord, isExistingWord));
if (onUnsupportedWordEntered != null)
onUnsupportedWordEntered(this, new UnsupportedWordEventArgs(unsupportedWord, isExistingWord));
if (IsMyTurn && onMyPathIsUnsupported != null)
onMyPathIsUnsupported(this, new UnsupportedWordEventArgs(unsupportedWord, isExistingWord));
}

private void CheckExample()
private void CheckExample(int watchdogID)
{
string example = GetExampleWord();
if (string.IsNullOrWhiteSpace(example))
return;
if (string.Equals(example, _exampleWordCache, StringComparison.InvariantCultureIgnoreCase))
return;
_exampleWordCache = example;
Log(ConsoleManager.LogType.Info, "Example submitted: " + example);
Log(ConsoleManager.LogType.Info, "Example submitted: " + example, watchdogID);
PathFinder.NewPathList.Add(example);
}

void Log(ConsoleManager.LogType logtype, string Content) => ConsoleManager.Log(logtype, Content, $"{GetHandlerName()} - #{_watchdogTask.Id.ToString()}");
private int CurrentWatchdogID => _watchdogTask == null ? -1 : _watchdogTask.Id;

void Log(ConsoleManager.LogType logtype, string Content, int watchdogID) => ConsoleManager.Log(logtype, Content, $"{GetHandlerName()} - #{watchdogID}");

private ResponsePresentedWord GetPresentedWord()
{
Expand Down Expand Up @@ -305,18 +323,20 @@ public MyTurnEventArgs(ResponsePresentedWord word, string missionChar)
}
}

public class WrongWordEventArgs : EventArgs
public class UnsupportedWordEventArgs : EventArgs
{
public string Word;
public Boolean IsExistingWord;

public WrongWordEventArgs(string word, bool isExistingWord)
public UnsupportedWordEventArgs(string word, bool isExistingWord)
{
Word = word;
IsExistingWord = isExistingWord;
}
}

public string GetID() => $"{GetHandlerName()} - #{(_watchdogTask == null ? "Global" : _watchdogTask.Id.ToString())}";

// These methods should be overridded
public abstract string GetSiteURLPattern();
public abstract string GetHandlerName();
Expand Down
47 changes: 27 additions & 20 deletions MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,33 +125,37 @@ private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
{
if (Handler != null)
{
ConsoleManager.Log(ConsoleManager.LogType.Info, $"Unregistered previous handler: {Handler.GetID()}", MAINTHREAD_NAME);

// Unregister previous handler
Handler.GameStartedEvent -= CommonHandler_GameStart;
Handler.GameEndedEvent -= CommonHandler_GameEnd;
Handler.MyTurnEvent -= CommonHandler_MyTurnEvent;
Handler.MyTurnEndedEvent -= CommonHandler_MyTurnEndEvent;
Handler.WrongWordEvent -= CommonHandler_WrongPathEvent;
Handler.MyPathIsWrongEvent -= CommonHandler_MyPathIsWrong;
Handler.RoundChangeEvent -= CommonHandler_RoundChangeEvent;
Handler.onGameStarted -= CommonHandler_GameStart;
Handler.onGameEnded -= CommonHandler_GameEnd;
Handler.onMyTurn -= CommonHandler_MyTurnEvent;
Handler.onMyTurnEnded -= CommonHandler_MyTurnEndEvent;
Handler.onUnsupportedWordEntered -= CommonHandler_onUnsupportedWordEntered;
Handler.onMyPathIsUnsupported -= CommonHandler_MyPathIsUnsupported;
Handler.onRoundChange -= CommonHandler_RoundChangeEvent;
Handler.StopWatchdog();
Handler = null;
}

// Initialize handler and Register event handlers
string url = e.Url;
Handler = CommonHandler.getHandler(url);
if (Handler != null)
{
ConsoleManager.Log(ConsoleManager.LogType.Info, $"Using handler: {Handler.GetHandlerName()}", MAINTHREAD_NAME);
Handler.GameStartedEvent += CommonHandler_GameStart;
Handler.GameEndedEvent += CommonHandler_GameEnd;
Handler.MyTurnEvent += CommonHandler_MyTurnEvent;
Handler.MyTurnEndedEvent += CommonHandler_MyTurnEndEvent;
Handler.WrongWordEvent += CommonHandler_WrongPathEvent;
Handler.MyPathIsWrongEvent += CommonHandler_MyPathIsWrong;
Handler.RoundChangeEvent += CommonHandler_RoundChangeEvent;
browser.FrameLoadEnd -= Browser_FrameLoadEnd;

Handler.onGameStarted += CommonHandler_GameStart;
Handler.onGameEnded += CommonHandler_GameEnd;
Handler.onMyTurn += CommonHandler_MyTurnEvent;
Handler.onMyTurnEnded += CommonHandler_MyTurnEndEvent;
Handler.onUnsupportedWordEntered += CommonHandler_onUnsupportedWordEntered;
Handler.onMyPathIsUnsupported += CommonHandler_MyPathIsUnsupported;
Handler.onRoundChange += CommonHandler_RoundChangeEvent;
Handler.StartWatchdog();

browser.FrameLoadEnd -= Browser_FrameLoadEnd;
ConsoleManager.Log(ConsoleManager.LogType.Info, $"Using handler: {Handler.GetID()}", MAINTHREAD_NAME);

ConsoleManager.Log(ConsoleManager.LogType.Info, "Browser frame-load end.", MAINTHREAD_NAME);
RemoveAd();
Expand Down Expand Up @@ -312,9 +316,9 @@ private void StartPathFinding(CommonHandler.ResponsePresentedWord word, string m
}
}

private void CommonHandler_WrongPathEvent(object sender, EventArgs e)
private void CommonHandler_onUnsupportedWordEntered(object sender, EventArgs e)
{
var i = ((CommonHandler.WrongWordEventArgs)e);
var i = ((CommonHandler.UnsupportedWordEventArgs)e);
bool isInexistent = !i.IsExistingWord;
string theWord = i.Word;
if (isInexistent)
Expand All @@ -324,9 +328,9 @@ private void CommonHandler_WrongPathEvent(object sender, EventArgs e)
PathFinder.AddToUnsupportedWord(theWord, isInexistent);
}

private void CommonHandler_MyPathIsWrong(object sender, EventArgs e)
private void CommonHandler_MyPathIsUnsupported(object sender, EventArgs e)
{
var word = ((CommonHandler.WrongWordEventArgs)e).Word;
var word = ((CommonHandler.UnsupportedWordEventArgs)e).Word;
ConsoleManager.Log(ConsoleManager.LogType.Info, $"My path '{word}' is wrong.", MAINTHREAD_NAME);

if (!CurrentConfig.AutoFix)
Expand Down Expand Up @@ -371,7 +375,10 @@ private void CommonHandler_GameEnd(object sender, EventArgs e)
SetSearchState(null, false);
ResetPathList();
if (CurrentConfig.AutoDBUpdateMode == Config.DBAUTOUPDATE_GAME_END_INDEX)
{
ChangeStatusBar(CurrentStatus.DB_Job, "자동 업데이트");
PathFinder.AutoDBUpdate();
}
ChangeStatusBar(CurrentStatus.Wait);
}

Expand Down

0 comments on commit abadb4c

Please sign in to comment.