diff --git a/LilithPort/LilithPort.vcxproj b/LilithPort/LilithPort.vcxproj index 1cf38b4..4380abf 100644 --- a/LilithPort/LilithPort.vcxproj +++ b/LilithPort/LilithPort.vcxproj @@ -19,7 +19,7 @@ Application - v140_xp + v140 Unicode Pure true @@ -63,7 +63,7 @@ ProgramDatabase - Shlwapi.lib + Shlwapi.lib;ws2_32.lib false true true @@ -81,7 +81,7 @@ ProgramDatabase - Shlwapi.lib + Shlwapi.lib;ws2_32.lib false true Windows diff --git a/LilithPort/MainForm.cpp b/LilithPort/MainForm.cpp index f4b93fb..10e2c56 100644 --- a/LilithPort/MainForm.cpp +++ b/LilithPort/MainForm.cpp @@ -105,12 +105,7 @@ void MainForm::Begin() WriteMessage(L"Server initialization complete.\n[MOTD]-------------------\n", SystemMessageColor); // Welcomeメッセージの表示 - int len = _tcslen(MTOPTION.WELCOME); - for(int i = 0; i < len; i++){ - if(MTOPTION.WELCOME[i] == _T('\t')){ - MTOPTION.WELCOME[i] = _T('\n'); - } - } + ReplaceWelcomeTab(true); richTextBoxLog->SelectionFont = gcnew Drawing::Font(richTextBoxLog->Font->FontFamily, richTextBoxLog->Font->Size + 2); richTextBoxLog->SelectionColor = TalkMessageColor; richTextBoxLog->SelectionBackColor = NoticeBackColor; @@ -348,7 +343,7 @@ void MainForm::Begin() WriteMessage(L"Anonymous server: chat and names are invisible.\n", SystemMessageColor); //fixme: hard translation (野良サーバ) ListView = LV_BLIND; - listBoxMember->Items[0] = gcnew String(L"Open Match"); //fixme: hard translation (野試合会場) + listBoxMember->Items[0] = gcnew String(L"Anonymous Mode"); //fixme: hard translation (野試合会場) } } @@ -460,6 +455,9 @@ void MainForm::ReceivePackets(IAsyncResult^ asyncResult) case PH_PING: rcv[0] = PH_PONG; UDP->Send(rcv, rcv->Length, ep); + if (MTINFO.DEBUG) { + form->WriteMessage(String::Format(L"Ping from {0}\n", ep), DebugMessageColor); + } break; case PH_PONG: @@ -618,14 +616,9 @@ void MainForm::ReceivePackets(IAsyncResult^ asyncResult) } // Welcomeメッセージ - for(UINT j = 0; j < _tcslen(MTOPTION.WELCOME); j++){ - if(MTOPTION.WELCOME[j] == _T('\t')){ - MTOPTION.WELCOME[j] = _T('\n'); - } - } + ReplaceWelcomeTab(true); i = _tcslen(MTOPTION.WELCOME)*2; - if(i > 0){ Thread::Sleep(50); @@ -1103,6 +1096,12 @@ void MainForm::ReceivePackets(IAsyncResult^ asyncResult) case PH_REQ_VS: + if (MemberList[0]->STATE == MS_SEEK && GameThread != nullptr) { + form->QuitGame(); + GameThread = nullptr; + Thread::Sleep(500); + } + // 準備時間が長すぎた場合は新規接続受付 if(NetVS != nullptr && MemberList[0]->STATE == MS_READY){ if((timeGetTime() - NetVS->START_UP) > TIME_OUT*2 + 1000){ @@ -1112,12 +1111,6 @@ void MainForm::ReceivePackets(IAsyncResult^ asyncResult) } } - if(MemberList[0]->STATE == MS_SEEK && GameThread != nullptr){ - form->QuitGame(); - GameThread = nullptr; - Thread::Sleep(500); - } - send = gcnew array(2); send[0] = PH_RES_VS; send[1] = (BYTE)MemberList[0]->STATE; @@ -1835,7 +1828,7 @@ void MainForm::ReceivePackets(IAsyncResult^ asyncResult) } catch(ObjectDisposedException^){ // UDP接続終了 - if(UDP != nullptr){ + if(UDP != nullptr && MTOPTION.CONNECTION_TYPE != CT_FREE){ UDP = nullptr; form->WriteMessage(L"Connection was interrupted!\n", SystemMessageColor); } @@ -2008,6 +2001,11 @@ void MainForm::RunGame(Object^ obj) // 送信間隔を計算 if(run_type == RT_VS){ + if (NetVS == nullptr) { + WriteMessage(L"An error occurred. This may be caused by you and your opponent having sent a match request at the same time.", ErrorMessageColor); + return; + } + NetVS->INTERVAL = 0; NetVS->INTERVAL2 = 0; @@ -3009,7 +3007,9 @@ void MainForm::RunGame(Object^ obj) ChangeState((BYTE)MS_REST); } else{ - ChangeState((BYTE)MS_FREE); + if (MemberList[0]->STATE != MS_SEEK) { + ChangeState((BYTE)MS_FREE); + } } } @@ -3548,7 +3548,11 @@ void MainForm::RunAutoRest() { GetLastInputInfo(&li); te = GetTickCount(); to = MTOPTION.AUTO_REST_TIME; - //WriteMessage(String::Format(L"{0}秒経過\n", ((te-li.dwTime)/1000) ), DebugMessageColor); + + if (MTINFO.DEBUG) { + //WriteMessage(String::Format(L"{0} seconds elapsed.\n", ((te-li.dwTime)/1000) ), DebugMessageColor); + } + if(((te-li.dwTime)/1000) >= UINT(to*60)){ // フリー状態なら休憩状態にする if(UDP != nullptr && MemberList[0]->STATE == MS_FREE){ @@ -3567,7 +3571,8 @@ void MainForm::ChangeSeek() { ChangeState((BYTE)MS_SEEK); WriteMessage(L"Seek mode set to ON.\n", SystemMessageColor); WriteTime(0, SystemMessageColor); - WriteMessage(String::Format(L"{0} is now in seek mode.\n", MemberList[0]->NAME), SystemMessageColor); + WriteMessage(String::Format(L"{0} is now in seek mode.\n", + ServerMode == SM_NORA ? L"◆" : MemberList[0]->NAME), SystemMessageColor); } else if(MemberList[0]->STATE == MS_SEEK){ if(GameThread != nullptr && GameThread->IsAlive){ @@ -3578,7 +3583,8 @@ void MainForm::ChangeSeek() { WriteMessage(L"Seek mode set to OFF.\n", SystemMessageColor); WriteTime(0, SystemMessageColor); - WriteMessage(String::Format(L"{0} has left seek mode.\n", MemberList[0]->NAME), SystemMessageColor); + WriteMessage(String::Format(L"{0} has left seek mode.\n", + ServerMode == SM_NORA ? L"◆" : MemberList[0]->NAME), SystemMessageColor); } } void MainForm::ChangeLogWordWrap() { @@ -3592,18 +3598,27 @@ void MainForm::ChangeLogWordWrap() { } } void MainForm::ClearLog(){ - if(MessageBox::Show(L"This will remove all but the last 10 lines of the log.\nAre you sure you want to clear the log?", L"Clear Log", MessageBoxButtons::YesNo, MessageBoxIcon::Question) == ::DialogResult::Yes){ + if(MessageBox::Show(L"This will remove the entire log.\n" + "Are you sure you want to clear the log?", L"Clear Log", + MessageBoxButtons::YesNo, MessageBoxIcon::Question) == ::DialogResult::Yes){ }else{ return; } Monitor::Enter(richTextBoxLog); try{ - int len = richTextBoxLog->Lines->Length; // 全体行数 - if(len > 10){ - int index = richTextBoxLog->GetFirstCharIndexFromLine(len-11); - richTextBoxLog->SelectionStart=0; - richTextBoxLog->Select(0, index); - richTextBoxLog->SelectedText= L"[Deleted]\n"; + richTextBoxLog->Clear(); + WriteTime(0, SystemMessageColor); + WriteMessage(L"[Deleted]\n", SystemMessageColor); + + if (MemberList[0]->TYPE == CT_FREE) return; + + if (MTOPTION.LOG_CLEAR_WITHOUT_WELCOME) { + WriteMessage(L"[MOTD]-------------------------\n", SystemMessageColor); + richTextBoxLog->SelectionFont = gcnew Drawing::Font(richTextBoxLog->Font->FontFamily, richTextBoxLog->Font->Size + 2); + richTextBoxLog->SelectionColor = TalkMessageColor; + richTextBoxLog->SelectionBackColor = NoticeBackColor; + richTextBoxLog->AppendText(gcnew String(MTOPTION.WELCOME) + "\n"); + WriteMessage(L"-------------------------------\n", SystemMessageColor); } } catch(Exception ^e){ @@ -3612,4 +3627,28 @@ void MainForm::ClearLog(){ finally{ Monitor::Exit(richTextBoxLog); } +} + +void MainForm::SaveLog() { + // 形式別ログ保存 + String^ path = gcnew String(MTOPTION.PATH); + String^ file = String::Format("LilithPort_{0}.{1}", DateTime::Now.ToString("yyyyMMdd-HHmmss"), + MTOPTION.LOG_FORMAT_RTF ? "rtf" : "txt"); + path += file; + Monitor::Enter(richTextBoxLog); + try { + if (MTOPTION.LOG_FORMAT_RTF) { + richTextBoxLog->SaveFile(path, RichTextBoxStreamType::RichText); + } + else { + richTextBoxLog->SaveFile(path, RichTextBoxStreamType::PlainText); + } + } + catch (Exception ^e) { + WriteErrorLog(e->ToString(), "SaveLog"); + } + finally { + Monitor::Exit(richTextBoxLog); + } + WriteMessage(String::Format(L"Log written to {0}", file), SystemMessageColor); } \ No newline at end of file diff --git a/LilithPort/MainForm.h b/LilithPort/MainForm.h index a39de8c..173af92 100644 --- a/LilithPort/MainForm.h +++ b/LilithPort/MainForm.h @@ -1023,6 +1023,7 @@ private: System::Windows::Forms::ContextMenu^ contextMenuStrip2; void ChangeSeek(); void ChangeLogWordWrap(); void ClearLog(); + void SaveLog(); void PacketSendAllMember(array^% datagram, UINT received_id); static void SendPackets(IAsyncResult^ asyncResult); @@ -1673,7 +1674,7 @@ private: System::Windows::Forms::ContextMenu^ contextMenuStrip2; Monitor::Enter(MemberList); try{ for(int i = 1; i < MemberList->Count; i++){ - if(MemberList[i]->STATE == MS_FREE && MemberList[i]->TYPE != CT_CLIENT){ + if(MemberList[i]->STATE == MS_FREE || MemberList[i]->STATE == MS_SEEK) { list->Add(i); } } @@ -1704,22 +1705,7 @@ private: System::Windows::Forms::ContextMenu^ contextMenuStrip2; ClearLog(); } else if(textBoxInput->Text->StartsWith("/log", StringComparison::OrdinalIgnoreCase)){ - String^ path = gcnew String(MTOPTION.PATH); - String^ file = String::Format(L"MT_{0}.rtf", DateTime::Now.ToString("yyMMdd-HHmmss")); - path += file; - - Monitor::Enter(richTextBoxLog); - try{ - richTextBoxLog->SaveFile(path, RichTextBoxStreamType::RichText); - } - catch(Exception ^e){ - WriteErrorLog(e->ToString(), "SaveLog"); - } - finally{ - Monitor::Exit(richTextBoxLog); - } - - WriteMessage(String::Format(L"Log saved to \"{0}\".\n", file), SystemMessageColor); + SaveLog(); } else if(textBoxInput->Text->StartsWith("/debug", StringComparison::OrdinalIgnoreCase)){ MTINFO.DEBUG ^= 1; @@ -1839,56 +1825,6 @@ private: System::Windows::Forms::ContextMenu^ contextMenuStrip2; //Thread::Sleep(100 * 1000); //ChangeState((BYTE)MS_FREE); - - /* - richTextBoxLog->SelectionStart = richTextBoxLog->Text->Length; - richTextBoxLog->SelectionColor = ErrorMessageColor; - richTextBoxLog->AppendText("hogehoge\n"); - */ - - - - - // 強制キック - //array^ send = gcnew array(3){ PH_LOST, 0xFF, 0xFF }; - //IPEndPoint^ ep = gcnew IPEndPoint(IPAddress::Parse("221.79.20.188")->Address, 7500); - //UDP->BeginSend(send, send->Length, ep, gcnew AsyncCallback(SendPackets), UDP); - - // ping - //IPEndPoint^ ep = gcnew IPEndPoint(IPAddress::Parse("220.147.87.48")->Address, 4040); - //array^ ping = gcnew array(1){ PH_PING }; - //Ping = timeGetTime(); - //UDP->BeginSend(ping, 1, ep, gcnew AsyncCallback(SendPackets), UDP); - - // なりきり - /* - IPEndPoint^ ep = gcnew IPEndPoint(IPAddress::Parse("220.147.87.48")->Address, 4040); - BYTE len = (BYTE)(16); - array^ msg = gcnew array(4 + len); - - msg[0] = PH_MESSAGE; - Array::Copy(BitConverter::GetBytes(207), 0, msg, 1, 2); - msg[3] = len; - Array::Copy(Encoding::Unicode->GetBytes("それほどでもない"), 0, msg, 4, len); - - UDP->BeginSend(msg, msg->Length, ep, gcnew AsyncCallback(SendPackets), UDP); - */ - - - /*// MTSPアドレスデコード - IPEndPoint^ ep = gcnew IPEndPoint(MTDecryptionIP(""), 7500); - WriteMessage(String::Format(L"{0}", ep), DebugMessageColor); - //*/ - - /*// LilithPortアドレスデコード - IPEndPoint^ ep = gcnew IPEndPoint(DecryptionIP("", true), 7500); - WriteMessage(String::Format(L"{0}", ep), DebugMessageColor); - //*/ - - /*// メンバーリスト手動削除 - MemberList->RemoveAt(listBoxMember->SelectedIndex); - listBoxMember->Items->RemoveAt(listBoxMember->SelectedIndex); - //*/ } } @@ -2048,7 +1984,7 @@ private: System::Windows::Forms::ContextMenu^ contextMenuStrip2; Array::Copy(BitConverter::GetBytes(0), 0, send, 1, 2); UDP->Send(send, 3, MemberList[1]->IP_EP); - WriteMessage(L"Manually updated the players list. (The list is usually updated continuously as manual requests place a load on the server.)\n", SystemMessageColor); + WriteMessage(L"Manually updated the players list. (The list is usually updated as players join, since manual requests place a load on the server.)\n", SystemMessageColor); } void WriteStatus(String^ msg){ toolStripStatusLabel->Text = msg; @@ -2356,21 +2292,8 @@ private: System::Windows::Forms::ContextMenu^ contextMenuStrip2; TimerGetIPThread->Join(); } - if(MTINFO.DEBUG){ - String^ path = gcnew String(MTOPTION.PATH); - path += "log.rtf"; - - Monitor::Enter(richTextBoxLog); - try{ - richTextBoxLog->SaveFile(path, RichTextBoxStreamType::RichText); - } - catch(Exception ^e){ - WriteErrorLog(e->ToString(), "SaveLog"); - } - finally{ - Monitor::Exit(richTextBoxLog); - } - } + // "Just in case," he said... + Thread::Sleep(500); } System::Void MainForm_FormClosed(System::Object^ sender, System::Windows::Forms::FormClosedEventArgs^ e) { @@ -2615,7 +2538,7 @@ private: System::Windows::Forms::ContextMenu^ contextMenuStrip2; } System::Void toolStripMenuItemVersion_Click(System::Object^ sender, System::EventArgs^ e) { - WriteMessage(L"LilithPort v1.07\nEnglish translation by longbyte1\n", SystemMessageColor); + WriteMessage(L"LilithPort v1.08\nEnglish translation by longbyte1\n", SystemMessageColor); } System::Void toolStripMenuItemExit_Click(System::Object^ sender, System::EventArgs^ e) { @@ -2805,22 +2728,7 @@ private: System::Windows::Forms::ContextMenu^ contextMenuStrip2; } System::Void toolStripMenuItemSaveLog_Click(System::Object^ sender, System::EventArgs^ e) { - String^ path = gcnew String(MTOPTION.PATH); - String^ file = String::Format(L"LilithPort_{0}.log", DateTime::Now.ToString("yyMMdd-HHmmss")); - path += file; - - Monitor::Enter(richTextBoxLog); - try{ - richTextBoxLog->SaveFile(path, RichTextBoxStreamType::PlainText); - } - catch(Exception ^e){ - WriteErrorLog(e->ToString(), "SaveLog"); - } - finally{ - Monitor::Exit(richTextBoxLog); - } - - WriteMessage(String::Format(L"Saved log to \"{0}\".\n", file), SystemMessageColor); + SaveLog(); } System::Void toolStripMenuItemReplay_Click(System::Object^ sender, System::EventArgs^ e) { diff --git a/LilithPort/OptionForm.cpp b/LilithPort/OptionForm.cpp index 9b38110..733ab3d 100644 --- a/LilithPort/OptionForm.cpp +++ b/LilithPort/OptionForm.cpp @@ -72,6 +72,7 @@ void OptionForm::SaveOption(bool apply){ MTOPTION.GET_IP_ENABLE = checkBoxGetIP->Checked; MTOPTION.SHOW_GAME_OPTION = checkBoxShowGameOption->Checked; MTOPTION.SHOW_RESULT = checkBoxShowResult->Checked; + MTOPTION.LOG_CLEAR_WITHOUT_WELCOME = checkBoxLogClearWithoutWelcome->Checked; // コメント if(textBoxComment->Text != gcnew String(MTOPTION.COMMENT)){ @@ -127,6 +128,9 @@ void OptionForm::SaveOption(bool apply){ } // 詳細設定 + // ログファイル保存形式 + MTOPTION.LOG_FORMAT_RTF = radioButtonLogRTF->Checked; + // 発言でウィンドウを点滅 MTOPTION.TALK_FLASH = checkBoxTalkFlash->Checked; // 名前が呼ばれたらウィンドウを点滅 diff --git a/LilithPort/OptionForm.h b/LilithPort/OptionForm.h index d4133d9..14463df 100644 --- a/LilithPort/OptionForm.h +++ b/LilithPort/OptionForm.h @@ -2239,6 +2239,7 @@ private: System::Windows::Forms::CheckBox^ checkBoxShowResult; checkBoxGetIP->Checked = MTOPTION.GET_IP_ENABLE; checkBoxShowGameOption->Checked = MTOPTION.SHOW_GAME_OPTION; checkBoxShowResult->Checked = MTOPTION.SHOW_RESULT; + checkBoxLogClearWithoutWelcome->Checked = MTOPTION.LOG_CLEAR_WITHOUT_WELCOME; numericUpDownMaxConnection->Value = MTOPTION.MAX_CONNECTION; trackBarBGM->Value = MTOPTION.BGM_VOLUME / 5; @@ -2255,6 +2256,10 @@ private: System::Windows::Forms::CheckBox^ checkBoxShowResult; checkBoxRand->Checked = MTOPTION.DISPLAY_RAND; checkBoxDivide->Checked = MTOPTION.REPLAY_DIVIDE; checkBoxWindowSize->Checked = MTOPTION.CHANGE_WINDOW_SIZE; + + radioButtonLogRTF->Checked = MTOPTION.LOG_FORMAT_RTF; + radioButtonLogTXT->Checked = !MTOPTION.LOG_FORMAT_RTF; + checkBoxTalkFlash->Checked = MTOPTION.TALK_FLASH; checkBoxNameFlash->Checked = MTOPTION.NAME_FLASH; checkBoxTeamRoundHP->Checked = MTOPTION.TEAM_ROUND_HP; diff --git a/LilithPort/stdafx.h b/LilithPort/stdafx.h index af4bafe..5e4e6d6 100644 --- a/LilithPort/stdafx.h +++ b/LilithPort/stdafx.h @@ -17,6 +17,18 @@ #pragma comment(lib, "user32.lib") #pragma comment(lib, "winmm.lib") +// UPnP +#include +#pragma comment(lib, "ole32.lib") +#pragma comment(lib, "oleauth32.lib") + +// IP acquisition +#include +#include + +//const IID UPNPNAT_CLSID = {0xAE1E00AA, 0x3FD5, 0x403C, {0x8A, 0x27, 0x2B, 0xBD, 0xC3, 0x0C, 0xD0, 0xE1}}; +//const IID IUPNPNAT_IID = {0xb171c812, 0xcc76, 0x485a, {0x94, 0xd8, 0xb6, 0xb3, 0xa2, 0x79, 0x4e, 0x99}}; + using namespace System; using namespace System::Windows::Forms; using namespace System::Collections; @@ -30,6 +42,7 @@ void ApplicationUnhandledException(Object^ sender, UnhandledExceptionEventArgs^ void LoadMTOption(); void SaveMTOption(); +void ReplaceWelcomeTab(bool TtoN); void SaveProfileOption(); void CheckMTOption(); void DeleteSection(TCHAR* obj); @@ -44,6 +57,8 @@ String^ EncryptionIP(String^ ip); String^ MTEncryptionIP(String^ ip); _int64 DecryptionIP(String^ cipher_ip, bool enc); _int64 MTDecryptionIP(String^ cipher_ip); +BSTR GetLocalIP(); +void UPnP_PortOpenClose(bool s, bool auto_close); UINT CipherRand(UINT32 seed = 0); UINT XorShift(UINT32 seed = 0); @@ -202,7 +217,7 @@ const BYTE VOLUME_SET_2_95_CODE[] = {0x50,0x8B,0x08,0xCC,0x52,0x50,0xFF,0x51,0x3 // バージョン情報 // LilithPort 1.03以上互換, それ以前はなし -const UINT LP_VERSION = 107; +const UINT LP_VERSION = 108; // 設定項目 const UINT MAX_NAME = 32; @@ -310,6 +325,7 @@ typedef struct _MT_SP_OPTION bool ALLOW_SPECTATOR; bool LOG_WORDWRAP; bool LOG_LOCK; + bool LOG_FORMAT_RTF; bool NAME_FLASH; bool TALK_FLASH; bool AFTER_REST; @@ -318,6 +334,7 @@ typedef struct _MT_SP_OPTION bool GET_IP_ENABLE; bool SHOW_GAME_OPTION; bool SHOW_RESULT; + bool LOG_CLEAR_WITHOUT_WELCOME; TCHAR PROFILE[MAX_ARRAY]; TCHAR PROFILE_LIST[MAX_PROFILE]; UINT PROFILE_INDEX;