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;