├── .gitignore ├── DummyClient ├── DummyClient.sln └── DummyClient │ ├── App.config │ ├── ChattingForm.Designer.cs │ ├── ChattingForm.cs │ ├── ChattingForm.resx │ ├── DummyClient.Designer.cs │ ├── DummyClient.cs │ ├── DummyClient.csproj │ ├── DummyClient.resx │ ├── LoginForm.Designer.cs │ ├── LoginForm.cs │ ├── LoginForm.resx │ ├── Program.cs │ ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings │ └── Source │ ├── Chatting │ ├── ChatWnd.cs │ ├── ChattingContents.cs │ └── ChattingPacketProcess.cs │ ├── ContentsProcess.cs │ ├── FormState.cs │ ├── Login │ ├── LoginContents.cs │ └── LoginPacketProcess.cs │ ├── Network │ ├── Network.cs │ ├── Packet.cs │ ├── PacketObfuscation.cs │ └── PacketUtil.cs │ ├── PacketGen │ ├── PacketClass.cs │ ├── PacketFactory.cs │ └── PacketHeader.cs │ ├── PacketProcess.cs │ └── ProgramState.cs ├── ServerCore ├── ChattingServer │ ├── ChattingServer.cpp │ ├── ChattingServer.vcxproj │ ├── ChattingServer.vcxproj.filters │ ├── ReadMe.txt │ ├── Server │ │ ├── ChattingProcess.cpp │ │ ├── ChattingProcess.h │ │ ├── User.h │ │ └── UserManager.h │ ├── config.xml │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h ├── DBAgent │ ├── DBAgent.vcxproj │ ├── DBAgent.vcxproj.filters │ ├── DBAgentProcess.cpp │ ├── DBAgentProcess.h │ ├── Query │ │ ├── QI_DB_REQ_ID_PW.h │ │ └── QI_DB_REQ_LOAD_DATA.h │ ├── ReadMe.txt │ ├── config.xml │ ├── main.cpp │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h ├── LoginServer │ ├── LoginServer.cpp │ ├── LoginServer.vcxproj │ ├── LoginServer.vcxproj.filters │ ├── ReadMe.txt │ ├── Server │ │ ├── LoginProcess.cpp │ │ └── LoginProcess.h │ ├── config.xml │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h ├── ServerCore.sln └── ServerLibrary │ ├── Contents │ ├── ContentsProcess.cpp │ └── ContentsProcess.h │ ├── Database │ ├── ADODatabase.cpp │ ├── ADODatabase.h │ ├── DBManager.cpp │ ├── DBManager.h │ ├── Database.h │ ├── Query.cpp │ ├── Query.h │ ├── QueryRecord.cpp │ ├── QueryRecord.h │ ├── QueryStatement.cpp │ └── QueryStatement.h │ ├── Debug │ └── msado15.tli │ ├── Net │ ├── Asio │ │ ├── ASIOServer.cpp │ │ ├── ASIOServer.h │ │ ├── ASIOSession.cpp │ │ └── ASIOSession.h │ ├── Iocp │ │ ├── IOCPServer.cpp │ │ ├── IOCPServer.h │ │ ├── IOCPSession.cpp │ │ └── IOCPSession.h │ ├── Packet.h │ ├── Packet │ │ ├── Package.h │ │ ├── PacketAnalyzer.cpp │ │ ├── PacketAnalyzer.h │ │ ├── PacketClass.h │ │ ├── PacketFactory.h │ │ ├── PacketHeader.h │ │ ├── PacketObfuscation.cpp │ │ ├── PacketObfuscation.h │ │ ├── Stream.cpp │ │ └── Stream.h │ ├── PacketHeader.h │ ├── PacketManager.h │ ├── Server.cpp │ ├── Server.h │ ├── Session.cpp │ ├── Session.h │ ├── SessionManager.cpp │ ├── SessionManager.h │ ├── SessionMonitor.cpp │ ├── SessionMonitor.h │ ├── Stream.h │ ├── Terminal │ │ ├── Terminal.cpp │ │ ├── Terminal.h │ │ ├── TerminalManager.cpp │ │ ├── TerminalManager.h │ │ ├── TerminalSession.cpp │ │ └── TerminalSession.h │ └── WinSocket.h │ ├── ReadMe.txt │ ├── ServerLibrary.h │ ├── ServerLibrary.vcxproj │ ├── ServerLibrary.vcxproj.filters │ ├── Shutdown.cpp │ ├── Shutdown.h │ ├── Util │ ├── Assert.cpp │ ├── Assert.h │ ├── Clock.cpp │ ├── Clock.h │ ├── Config.cpp │ ├── Config.h │ ├── GameObject.h │ ├── Lock.cpp │ ├── Lock.h │ ├── Logger.cpp │ ├── Logger.h │ ├── MemoryLeak.h │ ├── Memory_LowFragmentationHeap.h │ ├── Minidump.cpp │ ├── Minidump.h │ ├── Monitoring.h │ ├── ProgramValidation.h │ ├── RandomMT.h │ ├── SMTPMail.cpp │ ├── SMTPMail.h │ ├── Singleton.h │ ├── Table.h │ ├── Task.cpp │ ├── Task.h │ ├── Thread.cpp │ ├── Thread.h │ ├── ThreadJobQueue.h │ ├── Type.h │ ├── Util.h │ ├── csv_parser │ │ ├── csv_parser.cpp │ │ └── csv_parser.hpp │ └── tinyXml │ │ ├── tinystr.cpp │ │ ├── tinystr.h │ │ ├── tinyxml.cpp │ │ ├── tinyxml.h │ │ ├── tinyxmlerror.cpp │ │ └── tinyxmlparser.cpp │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h ├── packetMaker ├── App.config ├── ClassMakePacket.cs ├── ClientClassMakePacket.cs ├── ExcelParser.cs ├── FactoryMakePacket.cs ├── HeaderMakePacket.cs ├── MakePacket.cs ├── MakePacketStruct.cs ├── ParseExcel.cs ├── Properties │ └── AssemblyInfo.cs ├── bin │ └── Debug │ │ ├── Packet.h │ │ ├── PacketHeader.h │ │ ├── packetMaker.vshost.exe.config │ │ └── packetMaker.vshost.exe.manifest ├── main.cs ├── obj │ └── Debug │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs │ │ └── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs ├── packetData.xlsx └── packetMaker.csproj └── 게임 기본 쿼리.sql /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 이 .gitignore 파일은 Microsoft(R) Visual Studio에서 자동으로 만들어졌습니다. 3 | ################################################################################ 4 | 5 | /ServerCore/.vs/ServerCore/v15/ipch 6 | /ServerCore/.vs/ServerCore/v15 7 | /ServerCore/ServerLibrary/Debug/ServerLibrary.idb 8 | /ServerCore/ServerLibrary/Debug/ServerLibrary.tlog 9 | /ServerCore/.vs/ServerCore/v15 10 | -------------------------------------------------------------------------------- /DummyClient/DummyClient.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DummyClient", "DummyClient\DummyClient.csproj", "{5150A5E2-B219-4A7B-B9A2-0E448EACCC8D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {5150A5E2-B219-4A7B-B9A2-0E448EACCC8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {5150A5E2-B219-4A7B-B9A2-0E448EACCC8D}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {5150A5E2-B219-4A7B-B9A2-0E448EACCC8D}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {5150A5E2-B219-4A7B-B9A2-0E448EACCC8D}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/ChattingForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace DummyClient 2 | { 3 | partial class ChattingForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.textBox_input_ = new System.Windows.Forms.TextBox(); 32 | this.richTextBox_view_ = new System.Windows.Forms.RichTextBox(); 33 | this.SuspendLayout(); 34 | // 35 | // textBox_input_ 36 | // 37 | this.textBox_input_.Location = new System.Drawing.Point(20, 314); 38 | this.textBox_input_.Name = "textBox_input_"; 39 | this.textBox_input_.Size = new System.Drawing.Size(456, 21); 40 | this.textBox_input_.TabIndex = 3; 41 | this.textBox_input_.KeyDown += new System.Windows.Forms.KeyEventHandler(this.textBox_input_KeyDown); 42 | // 43 | // richTextBox_view_ 44 | // 45 | this.richTextBox_view_.BackColor = System.Drawing.Color.Teal; 46 | this.richTextBox_view_.ForeColor = System.Drawing.Color.White; 47 | this.richTextBox_view_.Location = new System.Drawing.Point(20, 12); 48 | this.richTextBox_view_.Name = "richTextBox_view_"; 49 | this.richTextBox_view_.ReadOnly = true; 50 | this.richTextBox_view_.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical; 51 | this.richTextBox_view_.Size = new System.Drawing.Size(457, 296); 52 | this.richTextBox_view_.TabIndex = 2; 53 | this.richTextBox_view_.Text = ""; 54 | // 55 | // ChattingForm 56 | // 57 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); 58 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 59 | this.AutoSize = true; 60 | this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 61 | this.ClientSize = new System.Drawing.Size(498, 349); 62 | this.Controls.Add(this.textBox_input_); 63 | this.Controls.Add(this.richTextBox_view_); 64 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 65 | this.Name = "ChattingForm"; 66 | this.Text = "ChattingForm"; 67 | this.ResumeLayout(false); 68 | this.PerformLayout(); 69 | 70 | } 71 | 72 | #endregion 73 | 74 | private System.Windows.Forms.TextBox textBox_input_; 75 | private System.Windows.Forms.RichTextBox richTextBox_view_; 76 | } 77 | } -------------------------------------------------------------------------------- /DummyClient/DummyClient/ChattingForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace DummyClient 12 | { 13 | public partial class ChattingForm : Form 14 | { 15 | private ChatWnd chatWnd_ = null; 16 | 17 | public ChattingForm() 18 | { 19 | InitializeComponent(); 20 | Control.CheckForIllegalCrossThreadCalls = false; 21 | chatWnd_ = new ChatWnd(richTextBox_view_); 22 | Program.programState_.putMessage_ += new ProgramState.putMessageDele(pushText); 23 | } 24 | 25 | ~ChattingForm() 26 | { 27 | base.Dispose(); 28 | chatWnd_ = null; 29 | } 30 | 31 | private void textBox_input_KeyDown(object sender, KeyEventArgs e) 32 | { 33 | if (e.KeyCode == Keys.Enter) 34 | { 35 | String inputStr = textBox_input_.Text + Environment.NewLine; 36 | richTextBox_view_.Text += inputStr; 37 | textBox_input_.Clear(); 38 | 39 | PK_C_REQ_CHATTING packet = new PK_C_REQ_CHATTING(); 40 | packet.text_ = inputStr; 41 | 42 | Program.programState_.sendPacket(packet); 43 | packet = null; 44 | } 45 | e.Handled = true; 46 | } 47 | 48 | public void pushText(string text) 49 | { 50 | chatWnd_.pushText(text); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/ChattingForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/DummyClient.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace DummyClient 2 | { 3 | partial class DummyClient 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.mainPanel_ = new System.Windows.Forms.Panel(); 32 | this.SuspendLayout(); 33 | // 34 | // mainPanel_ 35 | // 36 | this.mainPanel_.Location = new System.Drawing.Point(5, 8); 37 | this.mainPanel_.Name = "mainPanel_"; 38 | this.mainPanel_.Size = new System.Drawing.Size(608, 420); 39 | this.mainPanel_.TabIndex = 0; 40 | // 41 | // DummyClient 42 | // 43 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); 44 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 45 | this.ClientSize = new System.Drawing.Size(624, 441); 46 | this.Controls.Add(this.mainPanel_); 47 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; 48 | this.Name = "DummyClient"; 49 | this.Text = "DummyClient"; 50 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.DummyClient_FormClosing); 51 | this.Shown += new System.EventHandler(this.DummyClient_Shown); 52 | this.ResumeLayout(false); 53 | 54 | } 55 | 56 | #endregion 57 | 58 | public System.Windows.Forms.Panel mainPanel_; 59 | 60 | } 61 | } 62 | 63 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/DummyClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace DummyClient 12 | { 13 | partial class DummyClient : Form 14 | { 15 | public DummyClient() 16 | { 17 | InitializeComponent(); 18 | Control.CheckForIllegalCrossThreadCalls = false; 19 | } 20 | 21 | private void DummyClient_Shown(object sender, EventArgs e) 22 | { 23 | Program.programState_.setState(PROGRAM_STATE.LOGIN, null, 0); 24 | } 25 | 26 | private void DummyClient_FormClosing(object sender, FormClosingEventArgs e) 27 | { 28 | Program.programState_.close(); 29 | this.Dispose(); 30 | Application.Exit(); 31 | } 32 | 33 | public void removePanelForm(ref Form form) 34 | { 35 | mainPanel_.Controls.Remove(form); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/DummyClient.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {5150A5E2-B219-4A7B-B9A2-0E448EACCC8D} 8 | WinExe 9 | Properties 10 | DummyClient 11 | DummyClient 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Form 49 | 50 | 51 | ChattingForm.cs 52 | 53 | 54 | Form 55 | 56 | 57 | DummyClient.cs 58 | 59 | 60 | Form 61 | 62 | 63 | LoginForm.cs 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | ChattingForm.cs 85 | 86 | 87 | DummyClient.cs 88 | 89 | 90 | LoginForm.cs 91 | 92 | 93 | ResXFileCodeGenerator 94 | Resources.Designer.cs 95 | Designer 96 | 97 | 98 | True 99 | Resources.resx 100 | 101 | 102 | SettingsSingleFileGenerator 103 | Settings.Designer.cs 104 | 105 | 106 | True 107 | Settings.settings 108 | True 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 123 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/DummyClient.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/LoginForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace DummyClient 2 | { 3 | partial class LoginForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.textBox_id_ = new System.Windows.Forms.TextBox(); 32 | this.textBox_pw_ = new System.Windows.Forms.TextBox(); 33 | this.label1 = new System.Windows.Forms.Label(); 34 | this.label2 = new System.Windows.Forms.Label(); 35 | this.button_login_ = new System.Windows.Forms.Button(); 36 | this.button_quit_ = new System.Windows.Forms.Button(); 37 | this.SuspendLayout(); 38 | // 39 | // textBox_id_ 40 | // 41 | this.textBox_id_.Location = new System.Drawing.Point(78, 25); 42 | this.textBox_id_.Name = "textBox_id_"; 43 | this.textBox_id_.Size = new System.Drawing.Size(109, 21); 44 | this.textBox_id_.TabIndex = 0; 45 | // 46 | // textBox_pw_ 47 | // 48 | this.textBox_pw_.Location = new System.Drawing.Point(78, 52); 49 | this.textBox_pw_.Name = "textBox_pw_"; 50 | this.textBox_pw_.PasswordChar = '*'; 51 | this.textBox_pw_.Size = new System.Drawing.Size(109, 21); 52 | this.textBox_pw_.TabIndex = 1; 53 | // 54 | // label1 55 | // 56 | this.label1.AutoSize = true; 57 | this.label1.Location = new System.Drawing.Point(33, 28); 58 | this.label1.Name = "label1"; 59 | this.label1.Size = new System.Drawing.Size(16, 12); 60 | this.label1.TabIndex = 2; 61 | this.label1.Text = "ID"; 62 | // 63 | // label2 64 | // 65 | this.label2.AutoSize = true; 66 | this.label2.Location = new System.Drawing.Point(10, 55); 67 | this.label2.Name = "label2"; 68 | this.label2.Size = new System.Drawing.Size(62, 12); 69 | this.label2.TabIndex = 3; 70 | this.label2.Text = "Password"; 71 | // 72 | // button_login_ 73 | // 74 | this.button_login_.Location = new System.Drawing.Point(12, 91); 75 | this.button_login_.Name = "button_login_"; 76 | this.button_login_.Size = new System.Drawing.Size(75, 23); 77 | this.button_login_.TabIndex = 4; 78 | this.button_login_.Text = "로그인"; 79 | this.button_login_.UseVisualStyleBackColor = true; 80 | this.button_login_.Click += new System.EventHandler(this.button_login_Click); 81 | // 82 | // button_quit_ 83 | // 84 | this.button_quit_.Location = new System.Drawing.Point(107, 92); 85 | this.button_quit_.Name = "button_quit_"; 86 | this.button_quit_.Size = new System.Drawing.Size(75, 23); 87 | this.button_quit_.TabIndex = 5; 88 | this.button_quit_.Text = "종료"; 89 | this.button_quit_.UseVisualStyleBackColor = true; 90 | this.button_quit_.Click += new System.EventHandler(this.button_quit); 91 | // 92 | // LoginForm 93 | // 94 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); 95 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 96 | this.AutoSize = true; 97 | this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 98 | this.ClientSize = new System.Drawing.Size(197, 126); 99 | this.Controls.Add(this.button_quit_); 100 | this.Controls.Add(this.button_login_); 101 | this.Controls.Add(this.label2); 102 | this.Controls.Add(this.label1); 103 | this.Controls.Add(this.textBox_pw_); 104 | this.Controls.Add(this.textBox_id_); 105 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 106 | this.Name = "LoginForm"; 107 | this.Text = "DummyLogin"; 108 | this.ResumeLayout(false); 109 | this.PerformLayout(); 110 | 111 | } 112 | 113 | #endregion 114 | 115 | private System.Windows.Forms.TextBox textBox_id_; 116 | private System.Windows.Forms.TextBox textBox_pw_; 117 | private System.Windows.Forms.Label label1; 118 | private System.Windows.Forms.Label label2; 119 | private System.Windows.Forms.Button button_login_; 120 | private System.Windows.Forms.Button button_quit_; 121 | } 122 | } -------------------------------------------------------------------------------- /DummyClient/DummyClient/LoginForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace DummyClient 12 | { 13 | public partial class LoginForm : Form 14 | { 15 | public LoginForm() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | private void button_login_Click(object sender, EventArgs e) 21 | { 22 | PK_C_REQ_ID_PW packet = new PK_C_REQ_ID_PW(); 23 | packet.id_ = textBox_id_.Text; 24 | packet.password_ = textBox_pw_.Text; 25 | Program.programState_.sendPacket(packet); 26 | } 27 | 28 | private void button_quit(object sender, EventArgs e) 29 | { 30 | this.Dispose(); 31 | Application.Exit(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/LoginForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace DummyClient 8 | { 9 | static class Program 10 | { 11 | public static DummyClient mainForm_ = null; 12 | public static ProgramState programState_ = null; 13 | /// 14 | /// 해당 응용 프로그램의 주 진입점입니다. 15 | /// 16 | [STAThread] 17 | static void Main() 18 | { 19 | Application.EnableVisualStyles(); 20 | Application.SetCompatibleTextRenderingDefault(false); 21 | 22 | mainForm_ = new DummyClient(); 23 | programState_ = new ProgramState(); 24 | Application.Run(mainForm_); 25 | Application.Exit(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DummyClient")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DummyClient")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("cc9a5d44-48de-407b-bb12-b15e72c5dccb")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.33440 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace DummyClient.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DummyClient.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.33440 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace DummyClient.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/Source/Chatting/ChatWnd.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace DummyClient 5 | { 6 | internal class ChatWnd 7 | { 8 | private enum TextView 9 | { 10 | LINE_MAX = 5000, 11 | } 12 | 13 | //--------------------------------------------// 14 | private RichTextBox outputView_; 15 | 16 | public ChatWnd(RichTextBox richTextBox) 17 | { 18 | this.outputView_ = richTextBox; 19 | } 20 | 21 | private void chattingMessageResize() 22 | { 23 | String str = outputView_.Text; 24 | int textLine = 0; 25 | 26 | while (true) { 27 | int idx = str.IndexOf(Environment.NewLine); 28 | if (idx < 0) { 29 | break; 30 | } 31 | str = str.Substring(idx + Environment.NewLine.Length); 32 | ++textLine; 33 | } 34 | 35 | if (textLine > (int)TextView.LINE_MAX) { 36 | String originalStr = outputView_.Text; 37 | 38 | int idx = originalStr.IndexOf(Environment.NewLine); 39 | originalStr = originalStr.Substring(idx + Environment.NewLine.Length); 40 | 41 | outputView_.Text = originalStr; 42 | } 43 | } 44 | 45 | public void textChanged(object sender, EventArgs e) 46 | { 47 | chattingMessageResize(); 48 | 49 | String str = outputView_.Text; 50 | int len = str.LastIndexOf('\n'); 51 | if (len < 0) { 52 | return; 53 | } 54 | outputView_.SelectionStart = len; 55 | outputView_.ScrollToCaret(); 56 | } 57 | 58 | public void pushText(string text) 59 | { 60 | if (outputView_ == null) { 61 | return; 62 | } 63 | outputView_.AppendText(text + Environment.NewLine); 64 | outputView_.ScrollToCaret(); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /DummyClient/DummyClient/Source/Chatting/ChattingContents.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DummyClient 8 | { 9 | class ChattingContents : ContentsProcess 10 | { 11 | public void recvChatting(PacketInterface rowPacket) 12 | { 13 | PK_S_ANS_CHATTING packet = (PK_S_ANS_CHATTING)rowPacket; 14 | Program.programState_.putMessage(packet.name_ + packet.text_); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/Source/Chatting/ChattingPacketProcess.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Forms; 7 | 8 | namespace DummyClient 9 | { 10 | class ChattingPacketProcess : PacketProcess 11 | { 12 | ChattingContents contents_ = null; 13 | 14 | public ChattingPacketProcess() 15 | { 16 | contents_ = new ChattingContents(); 17 | } 18 | 19 | public override void run(PacketInterface packet) 20 | { 21 | PacketType type = (PacketType)packet.type(); 22 | switch (type) { 23 | case PacketType.E_S_ANS_CHATTING: 24 | contents_.recvChatting(packet); 25 | return; 26 | } 27 | 28 | if (base.defaultRun(packet) == false) { 29 | #if DEBUG 30 | MessageBox.Show("잘못된 패킷이 수신되었습니다 : " + type.ToString(), "error", MessageBoxButtons.OK); 31 | Application.Exit(); 32 | #endif 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/Source/ContentsProcess.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | 3 | namespace DummyClient 4 | { 5 | // 컨텐츠 처리 6 | internal abstract class ContentsProcess 7 | { 8 | //Todo : 공통 처리를 아래와 같이 기술합니다 9 | /*static public void exitPacket(PacketInterface packet) 10 | { 11 | Program.programState_.close(); 12 | Application.Exit(); 13 | } 14 | */ 15 | } 16 | } -------------------------------------------------------------------------------- /DummyClient/DummyClient/Source/FormState.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Windows.Forms; 3 | 4 | namespace DummyClient 5 | { 6 | internal abstract class FormState 7 | { 8 | protected Form form_; 9 | protected Network network_; 10 | 11 | public abstract void open(string ip, uint port); 12 | 13 | protected void setForm() 14 | { 15 | form_.TopLevel = false; 16 | form_.Dock = System.Windows.Forms.DockStyle.Fill; 17 | Program.mainForm_.Invoke(new MethodInvoker(delegate() 18 | { 19 | form_.Parent = Program.mainForm_.mainPanel_; 20 | form_.Show(); 21 | })); 22 | } 23 | 24 | public void close() 25 | { 26 | Program.mainForm_.removePanelForm(ref form_); 27 | if (network_ != null) 28 | network_.disConnect(); 29 | 30 | Thread.Sleep(1); 31 | form_.Hide(); 32 | } 33 | 34 | public bool connectToServer(string ip, uint port) 35 | { 36 | if (network_ == null) 37 | network_ = new Network(); 38 | 39 | return network_.connect(ip, port); 40 | } 41 | 42 | public void sendPacket(ref PacketInterface packet) 43 | { 44 | network_.sendPacket(packet); 45 | } 46 | } 47 | 48 | internal class LoginFormState : FormState 49 | { 50 | //HACK : 이곳 매직코드는 처음 접속하는 51 | // 로그인 서버 ip랑 port 번호임 52 | private string loginIp_ = "127.0.0.1"; 53 | private uint loginPort_ = 9000; 54 | 55 | public override void open(string ip, uint port) 56 | { 57 | form_ = new LoginForm(); 58 | setForm(); 59 | if (!base.connectToServer(loginIp_, loginPort_)) { 60 | var result = MessageBox.Show("로그인 서버 연결에 실패. 다시 연결 시도 해볼까요?", 61 | "error", MessageBoxButtons.RetryCancel); 62 | if (result != DialogResult.Retry) { 63 | form_.Close(); 64 | Application.Exit(); 65 | } 66 | } 67 | network_.setPacketProcess(new LoginPacketProcess()); 68 | } 69 | } 70 | 71 | internal class ChattingFormState : FormState 72 | { 73 | public override void open(string ip, uint port) 74 | { 75 | form_ = new ChattingForm(); 76 | setForm(); 77 | if (!base.connectToServer(ip, port)) { 78 | MessageBox.Show("채팅 서버 연결에 실패 했습니다..", 79 | "error", MessageBoxButtons.OK); 80 | Program.programState_.setState(PROGRAM_STATE.LOGIN, null, 0); 81 | } 82 | network_.setPacketProcess(new ChattingPacketProcess()); 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /DummyClient/DummyClient/Source/Login/LoginContents.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Forms; 7 | 8 | namespace DummyClient 9 | { 10 | class LoginContents : ContentsProcess 11 | { 12 | public void S_ANS_ID_PW_FAIL(PacketInterface rowPacket) 13 | { 14 | MessageBox.Show("로그인 실패", "로그인", MessageBoxButtons.OK); 15 | } 16 | 17 | public void S_ANS_ID_PW_SUCCESS(PacketInterface rowPacket) 18 | { 19 | PK_S_ANS_ID_PW_SUCCESS packet = (PK_S_ANS_ID_PW_SUCCESS)rowPacket; 20 | 21 | Program.programState_.setState(PROGRAM_STATE.CHATTING, packet.ip_, packet.port_); 22 | Program.programState_.setName(packet.name_); 23 | 24 | PK_C_REQ_REGIST_CHATTING_NAME rPacket = new PK_C_REQ_REGIST_CHATTING_NAME(); 25 | rPacket.name_ = packet.name_; 26 | Program.programState_.sendPacket(rPacket); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/Source/Login/LoginPacketProcess.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Forms; 7 | 8 | namespace DummyClient 9 | { 10 | class LoginPacketProcess : PacketProcess 11 | { 12 | LoginContents contents_ = null; 13 | 14 | public LoginPacketProcess() 15 | { 16 | contents_ = new LoginContents(); 17 | } 18 | 19 | public override void run(PacketInterface packet) 20 | { 21 | PacketType type = (PacketType)packet.type(); 22 | switch (type) { 23 | case PacketType.E_S_ANS_ID_PW_FAIL: 24 | contents_.S_ANS_ID_PW_FAIL(packet); 25 | return; 26 | case PacketType.E_S_ANS_ID_PW_SUCCESS: 27 | contents_.S_ANS_ID_PW_SUCCESS(packet); 28 | return; 29 | } 30 | if (base.defaultRun(packet) == false) { 31 | #if DEBUG 32 | MessageBox.Show("잘못된 패킷이 수신되었습니다 : " + type.ToString(), "error", MessageBoxButtons.OK); 33 | Application.Exit(); 34 | #endif 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/Source/Network/Network.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Net.Sockets; 4 | using System.Threading; 5 | using System.Windows.Forms; 6 | 7 | namespace DummyClient 8 | { 9 | internal enum NET_STATE 10 | { 11 | START, 12 | CONNECTED, 13 | DISCONNECT, 14 | DISCONNECTED, 15 | } 16 | 17 | internal class Network 18 | { 19 | private NetworkStream stream_; 20 | 21 | private Thread readWorker_; 22 | private Thread heartBeatWorker_; 23 | 24 | private TcpClient client_; 25 | private NET_STATE state_ = NET_STATE.START; 26 | 27 | private PacketProcess packetProcee_; 28 | ~Network() 29 | { 30 | if (this.isConnected()) { 31 | this.disConnect(); 32 | } 33 | } 34 | 35 | NET_STATE state() 36 | { 37 | return state_; 38 | } 39 | 40 | public void close() 41 | { 42 | state_ = NET_STATE.DISCONNECTED; 43 | 44 | stream_.Close(); 45 | stream_.Flush(); 46 | client_.Close(); 47 | readWorker_.Abort(); 48 | heartBeatWorker_.Abort(); 49 | packetProcee_ = null; 50 | } 51 | 52 | public bool connect(string ip, uint port) 53 | { 54 | client_ = new TcpClient(); 55 | try { 56 | client_.Connect(ip, Convert.ToInt32(port)); 57 | } catch { 58 | MessageBox.Show("서버 연결 실패", "error", MessageBoxButtons.OK); 59 | return false; 60 | } 61 | state_ = NET_STATE.CONNECTED; 62 | 63 | stream_ = client_.GetStream(); 64 | 65 | readWorker_ = new Thread(new ThreadStart(receive)); 66 | readWorker_.Start(); 67 | 68 | heartBeatWorker_ = new Thread(new ThreadStart(heartBeat)); 69 | heartBeatWorker_.Start(); 70 | return true; 71 | } 72 | 73 | public void disConnect() 74 | { 75 | state_ = NET_STATE.DISCONNECT; 76 | PK_C_REQ_EXIT packet = new PK_C_REQ_EXIT(); 77 | this.sendPacket(packet); 78 | } 79 | 80 | public void setPacketProcess(PacketProcess packetProcess) 81 | { 82 | packetProcee_ = packetProcess; 83 | } 84 | 85 | private bool isConnected() 86 | { 87 | return state_ == NET_STATE.CONNECTED ? true : false; 88 | } 89 | 90 | public void receive() 91 | { 92 | try { 93 | while (this.isConnected()) { 94 | Byte[] packetByte = new Byte[client_.ReceiveBufferSize]; 95 | 96 | Int32 offset = 0; 97 | Int32 readLen = stream_.Read(packetByte, offset, packetByte.Length); 98 | 99 | PacketObfuscation.decodingHeader(ref packetByte, sizeof(Int32)); 100 | Int32 packetLen = PacketUtil.decodePacketLen(packetByte, ref offset); 101 | 102 | while (readLen < packetLen) { 103 | Byte[] remainPacket = new Byte[client_.ReceiveBufferSize]; 104 | Int32 remainLen = 0; 105 | remainLen = stream_.Read(remainPacket, 0, remainPacket.Length); 106 | Buffer.BlockCopy(remainPacket, 0, packetByte, readLen, remainLen); 107 | readLen += remainLen; 108 | } 109 | 110 | Byte[] packetData = new Byte[client_.ReceiveBufferSize]; 111 | Buffer.BlockCopy(packetByte, offset, packetData, 0, readLen - offset); 112 | PacketObfuscation.decodingData(ref packetData, packetData.Length); 113 | 114 | PacketInterface rowPacket = PacketUtil.packetAnalyzer(packetData); 115 | if (rowPacket == null && this.isConnected()) { 116 | MessageBox.Show("잘못된 패킷이 수신되었습니다", "error", MessageBoxButtons.OK); 117 | Application.Exit(); 118 | } 119 | packetProcee_.run(rowPacket); 120 | } 121 | this.close(); 122 | } catch (Exception e) { 123 | if (this.isConnected()) { 124 | MessageBox.Show("잘못된 처리 : " + e.ToString(), "error", MessageBoxButtons.OK); 125 | Application.Exit(); 126 | } 127 | } 128 | } 129 | 130 | public void sendPacket(PacketInterface packet) 131 | { 132 | try { 133 | packet.encode(); 134 | MemoryStream packetBlock = new MemoryStream(); 135 | 136 | Int32 packetLen = sizeof(Int32) + (Int32)packet.getStream().Length; 137 | 138 | Byte[] packetHeader = BitConverter.GetBytes(packetLen); 139 | PacketObfuscation.encodingHeader(ref packetHeader, (int)packetHeader.Length); 140 | packetBlock.Write(packetHeader, 0, (Int32)packetHeader.Length); 141 | 142 | Byte[] packetData = packet.getStream().ToArray(); 143 | PacketObfuscation.encodingData(ref packetData, (int)packetData.Length); 144 | packetBlock.Write(packetData, 0, (Int32)packetData.Length); 145 | 146 | Byte[] packetBytes = packetBlock.ToArray(); 147 | stream_.Write(packetBytes, 0, (int) packetBlock.Length); 148 | stream_.Flush(); 149 | 150 | packetBlock = null; 151 | } catch (Exception e) { 152 | if (this.isConnected()) { 153 | MessageBox.Show("잘못된 처리 : " + e.ToString(), "error", MessageBoxButtons.OK); 154 | Application.Exit(); 155 | } 156 | } 157 | } 158 | 159 | private void heartBeat() 160 | { 161 | while (this.isConnected()) { 162 | PK_C_NOTIFY_HEARTBEAT heartBeatPacket = new PK_C_NOTIFY_HEARTBEAT(); 163 | this.sendPacket(heartBeatPacket); 164 | Thread.Sleep(1000); 165 | } 166 | } 167 | } 168 | } -------------------------------------------------------------------------------- /DummyClient/DummyClient/Source/Network/Packet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace DummyClient 5 | { 6 | public interface PacketInterface 7 | { 8 | void encode(); 9 | void decode(byte[] packet, ref int offset); 10 | 11 | Int64 type(); 12 | MemoryStream getStream(); 13 | } 14 | 15 | public class PacketData 16 | { 17 | protected MemoryStream packet_ = new MemoryStream(); 18 | 19 | ~PacketData() 20 | { 21 | packet_ = null; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /DummyClient/DummyClient/Source/Network/PacketObfuscation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DummyClient 8 | { 9 | static class PacketObfuscation 10 | { 11 | static Byte[] key_ = Encoding.ASCII.GetBytes(PacketMakeDate.stamp()); 12 | 13 | static private void CalcXor(ref Byte[] packet, int packetOffset, int packetLen) 14 | { 15 | int keyIdx = packetOffset % key_.Length; 16 | for (int packetIdx = 0; packetIdx < packetLen; ++packetIdx) 17 | { 18 | packet[packetIdx] ^= key_[keyIdx++]; 19 | if (keyIdx == key_.Length) 20 | { 21 | keyIdx = 0; 22 | } 23 | } 24 | } 25 | 26 | static public void encodingHeader(ref Byte[] packet, int packetLen) 27 | { 28 | CalcXor(ref packet, 0, packetLen); 29 | } 30 | static public void encodingData(ref Byte[] packet, int packetLen) 31 | { 32 | CalcXor(ref packet, sizeof(Int32), packetLen); 33 | } 34 | 35 | static public void decodingHeader(ref Byte[] packet, int packetLen) 36 | { 37 | CalcXor(ref packet, 0, packetLen); 38 | } 39 | static public void decodingData(ref Byte[] packet, int packetLen) 40 | { 41 | CalcXor(ref packet, sizeof(Int32), packetLen); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/Source/Network/PacketUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text; 4 | 5 | namespace DummyClient 6 | { 7 | // 패킷의 구성 성분을 만든다 8 | public static class PacketUtil 9 | { 10 | //-------------------------------------------------------------------// 11 | //--- encodeing 부분 12 | public static void encodeHeader(MemoryStream packet, Int64 headerType) 13 | { 14 | PacketUtil.encode(packet, headerType); 15 | } 16 | 17 | public static void encode(MemoryStream packet, Byte value) 18 | { 19 | packet.Write(BitConverter.GetBytes(value), 0, sizeof(Byte)); 20 | } 21 | 22 | public static void encode(MemoryStream packet, Char value) 23 | { 24 | packet.Write(BitConverter.GetBytes(value), 0, sizeof(Char)); 25 | } 26 | 27 | public static void encode(MemoryStream packet, Int16 value) 28 | { 29 | packet.Write(BitConverter.GetBytes(value), 0, sizeof(Int16)); 30 | } 31 | 32 | public static void encode(MemoryStream packet, UInt16 value) 33 | { 34 | packet.Write(BitConverter.GetBytes(value), 0, sizeof(UInt16)); 35 | } 36 | 37 | public static void encode(MemoryStream packet, Int32 value) 38 | { 39 | packet.Write(BitConverter.GetBytes(value), 0, sizeof(Int32)); 40 | } 41 | 42 | public static void encode(MemoryStream packet, UInt32 value) 43 | { 44 | packet.Write(BitConverter.GetBytes(value), 0, sizeof(UInt32)); 45 | } 46 | 47 | public static void encode(MemoryStream packet, Int64 value) 48 | { 49 | packet.Write(BitConverter.GetBytes(value), 0, sizeof(Int64)); 50 | } 51 | 52 | public static void encode(MemoryStream packet, UInt64 value) 53 | { 54 | packet.Write(BitConverter.GetBytes(value), 0, sizeof(UInt64)); 55 | } 56 | 57 | public static void encode(MemoryStream packet, string str) 58 | { 59 | PacketUtil.encode(packet, (Int32)str.Length); 60 | packet.Write(Encoding.UTF8.GetBytes(str), 0, str.Length); 61 | } 62 | //-------------------------------------------------------------------// 63 | //---decoding 부분 64 | public static Int32 decodePacketLen(Byte[] data, ref Int32 offset) 65 | { 66 | return PacketUtil.decodeInt32(data, ref offset); 67 | } 68 | 69 | public static Int64 decodePacketType(Byte[] data, ref Int32 offset) 70 | { 71 | return PacketUtil.decodeInt64(data, ref offset); 72 | } 73 | 74 | public static Byte decodeByte(Byte[] data, ref Int32 offset) 75 | { 76 | Byte val = data[offset]; 77 | offset += sizeof(Byte); 78 | return val; 79 | } 80 | 81 | public static Char decodeInt8(Byte[] data, ref Int32 offset) 82 | { 83 | Char val = BitConverter.ToChar(data, offset); 84 | offset += sizeof(Char); 85 | return val; 86 | } 87 | 88 | public static Int16 decodeInt16(Byte[] data, ref Int32 offset) 89 | { 90 | Int16 val = BitConverter.ToInt16(data, offset); 91 | offset += sizeof(Int16); 92 | return val; 93 | } 94 | 95 | public static UInt16 decodeUInt16(Byte[] data, ref Int32 offset) 96 | { 97 | UInt16 val = BitConverter.ToUInt16(data, offset); 98 | offset += sizeof(UInt16); 99 | return val; 100 | } 101 | 102 | public static Int32 decodeInt32(Byte[] data, ref Int32 offset) 103 | { 104 | Int32 val = BitConverter.ToInt32(data, offset); 105 | offset += sizeof(Int32); 106 | return val; 107 | } 108 | 109 | public static UInt32 decodeUInt32(Byte[] data, ref Int32 offset) 110 | { 111 | UInt32 val = BitConverter.ToUInt32(data, offset); 112 | offset += sizeof(UInt32); 113 | return val; 114 | } 115 | 116 | public static Int64 decodeInt64(Byte[] data, ref Int32 offset) 117 | { 118 | Int64 val = BitConverter.ToInt64(data, offset); 119 | offset += sizeof(Int64); 120 | return val; 121 | } 122 | 123 | public static UInt64 decodeUInt64(Byte[] data, ref Int32 offset) 124 | { 125 | UInt64 val = BitConverter.ToUInt64(data, offset); 126 | offset += sizeof(UInt64); 127 | return val; 128 | } 129 | 130 | public static string decodestring(Byte[] data, ref Int32 offset) 131 | { 132 | Int32 strLen = PacketUtil.decodeInt32(data, ref offset); 133 | string str = System.Text.Encoding.ASCII.GetString(data, offset, strLen); 134 | offset += strLen; 135 | return str; 136 | } 137 | 138 | public static PacketInterface packetAnalyzer(Byte[] packetByte) 139 | { 140 | Int32 offset = 0; 141 | Int64 packetType = PacketUtil.decodePacketType(packetByte, ref offset); 142 | PacketInterface packet = PacketFactory.getPacket(packetType); 143 | if (packet == null) { 144 | return null; 145 | } 146 | 147 | // 데이터가 있으면 decoding 해서 넘기기 148 | if (offset < packetByte.Length) { 149 | packet.decode(packetByte, ref offset); 150 | } 151 | return packet; 152 | } 153 | } 154 | } -------------------------------------------------------------------------------- /DummyClient/DummyClient/Source/PacketGen/PacketFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Data; 7 | using System.IO; 8 | 9 | namespace DummyClient 10 | { 11 | public static class PacketFactory 12 | { 13 | public static PacketInterface getPacket(Int64 packetType) 14 | { 15 | switch ((PacketType)packetType) 16 | { 17 | case PacketType.E_C_REQ_EXIT: return new PK_C_REQ_EXIT(); 18 | case PacketType.E_S_ANS_EXIT: return new PK_S_ANS_EXIT(); 19 | case PacketType.E_I_NOTIFY_TERMINAL: return new PK_I_NOTIFY_TERMINAL(); 20 | case PacketType.E_C_NOTIFY_HEARTBEAT: return new PK_C_NOTIFY_HEARTBEAT(); 21 | case PacketType.E_C_REQ_ID_PW: return new PK_C_REQ_ID_PW(); 22 | case PacketType.E_S_ANS_ID_PW_FAIL: return new PK_S_ANS_ID_PW_FAIL(); 23 | case PacketType.E_S_ANS_ID_PW_SUCCESS: return new PK_S_ANS_ID_PW_SUCCESS(); 24 | case PacketType.E_I_DB_REQ_ID_PW: return new PK_I_DB_REQ_ID_PW(); 25 | case PacketType.E_I_DB_ANS_ID_PW: return new PK_I_DB_ANS_ID_PW(); 26 | case PacketType.E_I_CHTTING_NOTIFY_ID: return new PK_I_CHTTING_NOTIFY_ID(); 27 | case PacketType.E_I_DB_REQ_LOAD_DATA: return new PK_I_DB_REQ_LOAD_DATA(); 28 | case PacketType.E_I_DB_ANS_PARSE_DATA: return new PK_I_DB_ANS_PARSE_DATA(); 29 | case PacketType.E_I_LOGIN_NOTIFY_ID_LOADED: return new PK_I_LOGIN_NOTIFY_ID_LOADED(); 30 | case PacketType.E_C_REQ_REGIST_CHATTING_NAME: return new PK_C_REQ_REGIST_CHATTING_NAME(); 31 | case PacketType.E_C_REQ_CHATTING: return new PK_C_REQ_CHATTING(); 32 | case PacketType.E_S_ANS_CHATTING: return new PK_S_ANS_CHATTING(); 33 | } 34 | return null; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/Source/PacketGen/PacketHeader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Data; 7 | using System.IO; 8 | 9 | namespace DummyClient 10 | { 11 | static class PacketMakeDate 12 | { 13 | static public string stamp() 14 | { 15 | return "2015/03/14 13:14:41"; 16 | } 17 | } 18 | enum PacketType : long { 19 | /*128*/ E_C_REQ_EXIT = 128, 20 | /*129*/ E_S_ANS_EXIT = 129, 21 | /*130*/ E_I_NOTIFY_TERMINAL = 130, 22 | /*131*/ E_C_NOTIFY_HEARTBEAT = 131, 23 | /*132*/ E_C_REQ_ID_PW = 132, 24 | /*133*/ E_S_ANS_ID_PW_FAIL = 133, 25 | /*134*/ E_S_ANS_ID_PW_SUCCESS = 134, 26 | /*135*/ E_I_DB_REQ_ID_PW = 135, 27 | /*136*/ E_I_DB_ANS_ID_PW = 136, 28 | /*137*/ E_I_CHTTING_NOTIFY_ID = 137, 29 | /*138*/ E_I_DB_REQ_LOAD_DATA = 138, 30 | /*139*/ E_I_DB_ANS_PARSE_DATA = 139, 31 | /*140*/ E_I_LOGIN_NOTIFY_ID_LOADED = 140, 32 | /*141*/ E_C_REQ_REGIST_CHATTING_NAME = 141, 33 | /*142*/ E_C_REQ_CHATTING = 142, 34 | /*143*/ E_S_ANS_CHATTING = 143, 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /DummyClient/DummyClient/Source/PacketProcess.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | 3 | namespace DummyClient 4 | { 5 | internal abstract class PacketProcess 6 | { 7 | public bool defaultRun(PacketInterface packet) 8 | { 9 | PacketType type = (PacketType)packet.type(); 10 | //Todo : 공통 처리 패킷에 대한 정의 11 | //switch (type) { 12 | 13 | //} 14 | 15 | return false; 16 | } 17 | 18 | public abstract void run(PacketInterface packet); 19 | } 20 | } -------------------------------------------------------------------------------- /DummyClient/DummyClient/Source/ProgramState.cs: -------------------------------------------------------------------------------- 1 | namespace DummyClient 2 | { 3 | internal enum PROGRAM_STATE 4 | { 5 | LOGIN, 6 | CHATTING, 7 | MAX, 8 | } 9 | 10 | internal class ProgramState 11 | { 12 | private PROGRAM_STATE state_; 13 | private FormState formState_ = null; 14 | private string name_; 15 | 16 | public delegate void putMessageDele(string msg); 17 | public event putMessageDele putMessage_; 18 | 19 | private void changeState() 20 | { 21 | switch (state_) { 22 | case PROGRAM_STATE.LOGIN: 23 | formState_ = new LoginFormState(); 24 | break; 25 | 26 | case PROGRAM_STATE.CHATTING: 27 | formState_ = new ChattingFormState(); 28 | break; 29 | } 30 | } 31 | 32 | public void setState(PROGRAM_STATE state, string ip, uint port) 33 | { 34 | if (formState_ != null) 35 | formState_.close(); 36 | 37 | state_ = state; 38 | this.changeState(); 39 | formState_.open(ip, port); 40 | } 41 | 42 | public void setName(string name) 43 | { 44 | name_ = name; 45 | } 46 | 47 | public string name() 48 | { 49 | return name_; 50 | } 51 | 52 | public void sendPacket(PacketInterface packet) 53 | { 54 | this.formState_.sendPacket(ref packet); 55 | } 56 | 57 | public void putMessage(string msg) 58 | { 59 | putMessage_(msg); 60 | } 61 | 62 | public void close() 63 | { 64 | this.formState_.close(); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /ServerCore/ChattingServer/ChattingServer.cpp: -------------------------------------------------------------------------------- 1 | // ChattingServer.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | 6 | class SystemReport : public Work 7 | { 8 | void tick() 9 | { 10 | Monitoring &moniter = Monitoring::getInstance(); 11 | SLog(L"### cpu usage : %2.2f%%, memory usage : %uByte", moniter.processCpuUsage(), moniter.processMemUsage()); 12 | } 13 | }; 14 | 15 | void serverProcess() 16 | { 17 | shared_ptr server(new IOCPServer(new ChattingProcess())); 18 | SystemReport systemReport; 19 | const int MONITOR_REPORTING_SEC = 1; 20 | TaskManager::getInstance().add(&systemReport, MONITOR_REPORTING_SEC, TICK_INFINTY); 21 | if (!server->run()) { 22 | SLog(L"! error: server start fail"); 23 | return; 24 | } 25 | } 26 | 27 | int _tmain(int argc, _TCHAR* argv[]) 28 | { 29 | shared_ptr serverThread(new Thread(new thread_t(serverProcess), L"Server")); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /ServerCore/ChattingServer/ChattingServer.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 10 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 11 | 12 | 13 | {20b361c9-b1a9-4f43-9588-a758cfd21d57} 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | Source Files 22 | 23 | 24 | Source Files 25 | 26 | 27 | Server 28 | 29 | 30 | Server 31 | 32 | 33 | Server 34 | 35 | 36 | 37 | 38 | Source Files 39 | 40 | 41 | Source Files 42 | 43 | 44 | Server 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /ServerCore/ChattingServer/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : ChattingServer Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this ChattingServer application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your ChattingServer application. 9 | 10 | 11 | ChattingServer.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | ChattingServer.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | ChattingServer.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named ChattingServer.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /ServerCore/ChattingServer/Server/ChattingProcess.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ChattingServer/Server/ChattingProcess.cpp -------------------------------------------------------------------------------- /ServerCore/ChattingServer/Server/ChattingProcess.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | class ChattingProcess : public ContentsProcess 5 | { 6 | public: 7 | ChattingProcess(); 8 | private: 9 | void registSubPacketFunc(); 10 | 11 | static void I_CHTTING_NOTIFY_ID(Session *session, Packet *rowPacket); 12 | static void I_DB_ANS_PARSE_DATA(Session *session, Packet *rowPacket); 13 | static void C_REQ_REGIST_CHATTING_NAME(Session *session, Packet *rowPacket); 14 | static void C_REQ_CHATTING(Session *session, Packet *rowPacket); 15 | static void C_REQ_EXIT(Session *session, Packet *rowPacket); 16 | }; -------------------------------------------------------------------------------- /ServerCore/ChattingServer/Server/User.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | class User : public GameObject 5 | { 6 | Session *session_; 7 | public: 8 | User(Session *session) 9 | { 10 | session_ = session; 11 | } 12 | 13 | Session* session() 14 | { 15 | return session_; 16 | } 17 | 18 | void tick() 19 | { 20 | 21 | } 22 | }; -------------------------------------------------------------------------------- /ServerCore/ChattingServer/Server/UserManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | class User; 4 | class Session; 5 | 6 | class UserManager : public Singleton < UserManager > 7 | { 8 | unordered_map userPool_; 9 | 10 | public: 11 | void insert(User *user) 12 | { 13 | oid_t key = user->session()->id(); 14 | userPool_.insert(make_pair(key, user)); 15 | } 16 | 17 | void remove(oid_t id) 18 | { 19 | userPool_.erase(id); 20 | } 21 | 22 | User* at(oid_t id) 23 | { 24 | auto itr = userPool_.lower_bound(id); 25 | if (itr == userPool_.end()) { 26 | return nullptr; 27 | } 28 | return itr->second; 29 | } 30 | 31 | size_t size() 32 | { 33 | return userPool_.size(); 34 | } 35 | }; -------------------------------------------------------------------------------- /ServerCore/ChattingServer/config.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | Chatting Server 4 | 5 | 127.0.0.1 6 | 9200 7 | 5 8 | 9 | 10 | 11 | 127.0.0.1 12 | 9000 13 | 14 | 15 | 127.0.0.1 16 | 9100 17 | 18 | 19 | 20 | ./Log/LoginLog.log 21 | System 22 | WithFile 23 | 24 | 25 | 5 26 | 27 | 28 | 5 29 | 30 | -------------------------------------------------------------------------------- /ServerCore/ChattingServer/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // ChattingServer.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /ServerCore/ChattingServer/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | // TODO: reference additional headers your program requires here 14 | #include "ServerLibrary.h" 15 | 16 | #include "Server\User.h" 17 | #include "Server\UserManager.h" 18 | #include "Server\ChattingProcess.h" -------------------------------------------------------------------------------- /ServerCore/ChattingServer/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /ServerCore/DBAgent/DBAgent.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {c036e0a7-3539-4667-bd84-5a875627dd60} 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Query 35 | 36 | 37 | Query 38 | 39 | 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /ServerCore/DBAgent/DBAgentProcess.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/DBAgent/DBAgentProcess.cpp -------------------------------------------------------------------------------- /ServerCore/DBAgent/DBAgentProcess.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | class DBAgentProcess : public ContentsProcess 5 | { 6 | public: 7 | DBAgentProcess(); 8 | private: 9 | void registSubPacketFunc(); 10 | static void I_DB_REQ_ID_PW(Session *session, Packet *rowPacket); 11 | static void I_DB_REQ_LOAD_DATA(Session *session, Packet *rowPacket); 12 | }; -------------------------------------------------------------------------------- /ServerCore/DBAgent/Query/QI_DB_REQ_ID_PW.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/DBAgent/Query/QI_DB_REQ_ID_PW.h -------------------------------------------------------------------------------- /ServerCore/DBAgent/Query/QI_DB_REQ_LOAD_DATA.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/DBAgent/Query/QI_DB_REQ_LOAD_DATA.h -------------------------------------------------------------------------------- /ServerCore/DBAgent/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : DBAgent Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this DBAgent application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your DBAgent application. 9 | 10 | 11 | DBAgent.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | DBAgent.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | DBAgent.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named DBAgent.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /ServerCore/DBAgent/config.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | DBAgent 4 | 5 | 127.0.0.1 6 | 9100 7 | 2 8 | 9 | 10 | 11 | 127.0.0.1 12 | 9000 13 | 14 | 15 | 127.0.0.1 16 | 9200 17 | 18 | 19 | 20 | ./Log/DBAgent.log 21 | DBAgent 22 | WithFile 23 | 24 | 25 | 192.168.0.150 26 | GameDB 27 | gameServer 28 | testServer 29 | 5 30 | 31 | 32 | 5 33 | 34 | -------------------------------------------------------------------------------- /ServerCore/DBAgent/main.cpp: -------------------------------------------------------------------------------- 1 | // DBAgent.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "DBAgentProcess.h" 6 | 7 | void serverProcess() 8 | { 9 | shared_ptr server(new IOCPServer(new DBAgentProcess())); 10 | //std::shared_ptr server(new ServerASIO(2000)); 11 | if (!server->run()) { 12 | SLog(L"! error: server start fail"); 13 | return; 14 | } 15 | } 16 | 17 | int _tmain(int argc, _TCHAR* argv[]) 18 | { 19 | DBManager::getInstance().run(); 20 | 21 | shared_ptr serverThread(new Thread(new thread_t(serverProcess), L"DBAgent")); 22 | return 0; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /ServerCore/DBAgent/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // DBAgent.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /ServerCore/DBAgent/stdafx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/DBAgent/stdafx.h -------------------------------------------------------------------------------- /ServerCore/DBAgent/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /ServerCore/LoginServer/LoginServer.cpp: -------------------------------------------------------------------------------- 1 | // LoginServer.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | 6 | class SystemReport : public Work 7 | { 8 | void tick() 9 | { 10 | Monitoring &moniter = Monitoring::getInstance(); 11 | SLog(L"### cpu usage : %2.2f%%, memory usage : %uByte", moniter.processCpuUsage(), moniter.processMemUsage()); 12 | } 13 | }; 14 | 15 | void serverProcess() 16 | { 17 | shared_ptr server(new IOCPServer(new LoginProcess())); 18 | SystemReport systemReport; 19 | const int MONITOR_REPORTING_SEC = 1; 20 | TaskManager::getInstance().add(&systemReport, MONITOR_REPORTING_SEC, TICK_INFINTY); 21 | if (!server->run()) { 22 | SLog(L"! error: server start fail"); 23 | return; 24 | } 25 | } 26 | 27 | int _tmain(int argc, _TCHAR* argv[]) 28 | { 29 | shared_ptr serverThread(new Thread(new thread_t(serverProcess), L"Server")); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /ServerCore/LoginServer/LoginServer.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 10 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 11 | 12 | 13 | {0ac9e5ba-323d-49b9-ae81-fe1e703b44cc} 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | Server 22 | 23 | 24 | Source Files 25 | 26 | 27 | Source Files 28 | 29 | 30 | 31 | 32 | Source Files 33 | 34 | 35 | Source Files 36 | 37 | 38 | Server 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ServerCore/LoginServer/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : LoginServer Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this LoginServer application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your LoginServer application. 9 | 10 | 11 | LoginServer.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | LoginServer.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | LoginServer.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named LoginServer.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /ServerCore/LoginServer/Server/LoginProcess.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/LoginServer/Server/LoginProcess.cpp -------------------------------------------------------------------------------- /ServerCore/LoginServer/Server/LoginProcess.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | class LoginProcess : public ContentsProcess 5 | { 6 | public: 7 | LoginProcess(); 8 | private: 9 | void registSubPacketFunc(); 10 | static void C_REQ_ID_PW(Session *session, Packet *rowPacket); 11 | static void I_DB_ANS_ID_PW(Session *session, Packet *rowPacket); 12 | static void I_LOGIN_NOTIFY_ID_LOADED(Session *session, Packet *rowPacket); 13 | }; -------------------------------------------------------------------------------- /ServerCore/LoginServer/config.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | LoginServer 4 | 5 | 127.0.0.1 6 | 9000 7 | 5 8 | 9 | 10 | 11 | 127.0.0.1 12 | 9200 13 | 14 | 15 | 127.0.0.1 16 | 9100 17 | 18 | 19 | 20 | ./Log/LoginLog.log 21 | System 22 | WithFile 23 | 24 | 25 | 5 26 | 27 | 28 | 5 29 | 30 | -------------------------------------------------------------------------------- /ServerCore/LoginServer/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // LoginServer.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /ServerCore/LoginServer/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | #include "ServerLibrary.h" 17 | #include "./Server/LoginProcess.h" -------------------------------------------------------------------------------- /ServerCore/LoginServer/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Contents/ContentsProcess.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Contents/ContentsProcess.cpp -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Contents/ContentsProcess.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Contents/ContentsProcess.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Database/ADODatabase.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Database/ADODatabase.cpp -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Database/ADODatabase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #import "c:\Program Files\Common Files\System\ADO\msado15.dll" rename("EOF", "EndOfFile") 9 | #include "Database.h" 10 | 11 | typedef ADODB::_ConnectionPtr dbConnectionPtr; 12 | typedef ADODB::_CommandPtr commandPtr; 13 | typedef ADODB::_RecordsetPtr recordPtr; 14 | 15 | class ADODatabase : public Database 16 | { 17 | dbConnectionPtr dbConnection_; 18 | wstr_t connectionStr_; 19 | wstr_t dbName_; 20 | 21 | Thread *thread_; 22 | 23 | public: 24 | ADODatabase(); 25 | virtual ~ADODatabase(); 26 | 27 | HRESULT setConnectTimeOut(long second); 28 | void comError(const WCHAR *actionName, _com_error &e); 29 | 30 | bool connect(const WCHAR *provider, const WCHAR *serverName, const WCHAR *dbName, const WCHAR *id, const WCHAR *password); 31 | bool connect(const WCHAR *serverName, const WCHAR *dbName, const WCHAR *id, const WCHAR *password); 32 | bool connect(); 33 | bool connected(); 34 | bool disconnect(); 35 | 36 | void run(); 37 | 38 | private: 39 | void execute(); 40 | void process(); 41 | }; 42 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Database/DBManager.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | DBManager::DBManager() 4 | { 5 | xml_t config; 6 | if (!loadConfig(&config)) { 7 | return; 8 | } 9 | 10 | this->initialize(&config); 11 | } 12 | 13 | void DBManager::initialize(xml_t *config) 14 | { 15 | xmlNode_t *root = config->FirstChildElement("App")->FirstChildElement("DataBase"); 16 | if (!root) { 17 | SLog(L"@ not exist database setting"); 18 | return; 19 | } 20 | xmlNode_t *elem = root->FirstChildElement("ThreadCount"); 21 | sscanf_s(elem->GetText(), "%d", &workerCount_); 22 | 23 | array tmp; 24 | elem = root->FirstChildElement("ServerName"); 25 | StrConvA2W((char *) elem->GetText(), tmp.data(), tmp.max_size()); 26 | serverName_ = tmp.data(); 27 | 28 | elem = root->FirstChildElement("DB"); 29 | StrConvA2W((char *) elem->GetText(), tmp.data(), tmp.max_size()); 30 | dbName_ = tmp.data(); 31 | 32 | elem = root->FirstChildElement("Login"); 33 | StrConvA2W((char *) elem->GetText(), tmp.data(), tmp.max_size()); 34 | login_ = tmp.data(); 35 | 36 | elem = root->FirstChildElement("Password"); 37 | StrConvA2W((char *) elem->GetText(), tmp.data(), tmp.max_size()); 38 | password_ = tmp.data(); 39 | 40 | queryPool_ = new ThreadJobQueue(L"DBQueueJob"); 41 | 42 | for (int i = 0; i < workerCount_; ++i) { 43 | array patch = { 0, }; 44 | ADODatabase *adodb = new ADODatabase(); 45 | dbPool_.push_back(adodb); 46 | } 47 | this->run(); 48 | } 49 | 50 | DBManager::~DBManager() 51 | { 52 | SAFE_DELETE(queryPool_); 53 | 54 | for (auto db : dbPool_) { 55 | db->disconnect(); 56 | SAFE_DELETE(db); 57 | } 58 | } 59 | 60 | size_t DBManager::runQueryCount() 61 | { 62 | return queryPool_->size(); 63 | } 64 | 65 | void DBManager::pushQuery(Query *query) 66 | { 67 | queryPool_->push(query); 68 | } 69 | 70 | bool DBManager::popQuery(Query **query) 71 | { 72 | return queryPool_->pop(*query); 73 | } 74 | 75 | void DBManager::run() 76 | { 77 | for (auto db : dbPool_) { 78 | if (db->state() != DB_STOP) { 79 | continue; 80 | } 81 | 82 | if (!db->connect(serverName_.c_str(), dbName_.c_str(), login_.c_str(), password_.c_str())) { 83 | SErrLog(L"! db[%s] connection error", dbName_.c_str()); 84 | } 85 | db->run(); 86 | } 87 | } -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Database/DBManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | #include "ADODatabase.h" 4 | 5 | #define _db_manager DBManager::getInstance() 6 | 7 | class DBManager : public Singleton < DBManager > 8 | { 9 | int workerCount_; 10 | std::vector dbPool_; 11 | 12 | wstr_t serverName_; 13 | wstr_t dbName_; 14 | wstr_t login_; 15 | wstr_t password_; 16 | ThreadJobQueue *queryPool_; 17 | 18 | public: 19 | DBManager(); 20 | virtual ~DBManager(); 21 | 22 | void initialize(xml_t *config); 23 | 24 | size_t runQueryCount(); 25 | void pushQuery(Query *query); 26 | bool popQuery(Query **query); 27 | 28 | void run(); 29 | }; -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Database/Database.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Database/Database.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Database/Query.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | #include "QueryStatement.h" 4 | #include "QueryRecord.h" 5 | #include "Query.h" 6 | #include "ADODatabase.h" 7 | #include "DBManager.h" 8 | 9 | Query::Query() 10 | { 11 | statement_ = new QueryStatement(); 12 | } 13 | Query::~Query() 14 | { 15 | record_.close(); 16 | SAFE_DELETE(statement_); 17 | } 18 | 19 | void Query::setResult(recordPtr record) 20 | { 21 | record_.setRecord(record); 22 | } 23 | 24 | QueryRecord& Query::result() 25 | { 26 | return record_; 27 | } 28 | 29 | void Query::setStatement(QueryStatement *statement) 30 | { 31 | statement_ = statement; 32 | } 33 | 34 | QueryStatement* Query::statement() 35 | { 36 | return statement_; 37 | } -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Database/Query.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Database/Query.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Database/QueryRecord.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "QueryRecord.h" 3 | 4 | QueryRecord::QueryRecord() 5 | { 6 | record_.CreateInstance(__uuidof(ADODB::Recordset)); 7 | } 8 | 9 | QueryRecord::~QueryRecord() 10 | { 11 | if (record_ == nullptr) { 12 | return; 13 | } 14 | record_.Release(); 15 | record_ = nullptr; 16 | } 17 | 18 | void QueryRecord::errorReport(_com_error &e) { 19 | SLog(L"* Query error = %S", e.Description()); 20 | } 21 | 22 | recordPtr &QueryRecord::resultRecord() 23 | { 24 | return record_; 25 | } 26 | 27 | void QueryRecord::operator = (QueryRecord &lvalue) 28 | { 29 | record_ = lvalue.resultRecord(); 30 | } 31 | 32 | void QueryRecord::operator = (recordPtr &lvalue) 33 | { 34 | record_ = lvalue; 35 | } 36 | 37 | void QueryRecord::setRecord(recordPtr record) 38 | { 39 | record_ = record; 40 | } 41 | 42 | bool QueryRecord::opened() 43 | { 44 | return record_->State == ADODB::adStateOpen ? true : false; 45 | } 46 | 47 | void QueryRecord::close() 48 | { 49 | try{ 50 | if (record_ != nullptr && this->opened()) 51 | record_->Close(); 52 | } 53 | catch (_com_error &e){ 54 | this->errorReport(e); 55 | } 56 | } 57 | 58 | int QueryRecord::resultVal() 59 | { 60 | return resultVal_; 61 | } 62 | 63 | void QueryRecord::setResultVal(int result) 64 | { 65 | resultVal_ = result; 66 | } 67 | 68 | bool QueryRecord::isEof() 69 | { 70 | if (record_ == nullptr) { 71 | return true; 72 | } 73 | try { 74 | return record_->EndOfFile ? true : false; 75 | } 76 | catch (_com_error &e) { 77 | this->errorReport(e); 78 | } 79 | return false; 80 | } 81 | 82 | HRESULT QueryRecord::moveNext() 83 | { 84 | try { 85 | return record_->MoveNext(); 86 | } 87 | catch (_com_error &e) { 88 | this->errorReport(e); 89 | } 90 | return S_FALSE; 91 | } 92 | 93 | HRESULT QueryRecord::movePrevious() 94 | { 95 | try { 96 | return record_->MovePrevious(); 97 | } 98 | catch (_com_error &e) { 99 | this->errorReport(e); 100 | } 101 | return S_FALSE; 102 | } 103 | 104 | HRESULT QueryRecord::moveFirst() 105 | { 106 | try { 107 | return record_->MoveFirst(); 108 | } 109 | catch (_com_error &e) { 110 | this->errorReport(e); 111 | } 112 | return S_FALSE; 113 | } 114 | 115 | HRESULT QueryRecord::moveLast() 116 | { 117 | try { 118 | return record_->MoveLast(); 119 | } 120 | catch (_com_error &e) { 121 | this->errorReport(e); 122 | } 123 | return S_FALSE; 124 | } 125 | 126 | bool QueryRecord::get(char* fieldName, char* fieldValue) 127 | { 128 | try { 129 | _variant_t vtValue; 130 | vtValue = record_->Fields->GetItem(fieldName)->GetValue(); 131 | sprintf_s(fieldValue, DB_PARAM_SIZE, "%s", (LPCSTR)((_bstr_t)vtValue.bstrVal)); 132 | return true; 133 | } 134 | catch (_com_error &e) { 135 | this->errorReport(e); 136 | SLog(L"! error query field : %S", fieldName); 137 | } 138 | return false; 139 | } 140 | 141 | bool QueryRecord::get(char* fieldName, wchar_t* fieldValue) 142 | { 143 | try { 144 | _variant_t vtValue; 145 | vtValue = record_->Fields->GetItem(fieldName)->GetValue(); 146 | swprintf_s(fieldValue, DB_PARAM_SIZE, L"%s", (LPWSTR)((_bstr_t)vtValue.bstrVal)); 147 | return true; 148 | } 149 | catch (_com_error &e) { 150 | this->errorReport(e); 151 | SLog(L"! error query field : %S", fieldName); 152 | } 153 | return false; 154 | } 155 | 156 | bool QueryRecord::get(char* fieldName, int32_t& fieldValue) 157 | { 158 | try { 159 | _variant_t vtValue; 160 | vtValue = record_->Fields->GetItem(fieldName)->GetValue(); 161 | fieldValue = vtValue.intVal; 162 | return true; 163 | } 164 | catch (_com_error &e) { 165 | this->errorReport(e); 166 | SLog(L"! error query field : %S", fieldName); 167 | } 168 | return false; 169 | } 170 | 171 | bool QueryRecord::get(char* fieldName, int64_t& fieldValue) 172 | { 173 | try { 174 | _variant_t vtValue; 175 | vtValue = record_->Fields->GetItem(fieldName)->GetValue(); 176 | fieldValue = vtValue.intVal; 177 | return true; 178 | } 179 | catch (_com_error &e) { 180 | this->errorReport(e); 181 | SLog(L"! error query field : %S", fieldName); 182 | } 183 | return false; 184 | } 185 | 186 | bool QueryRecord::get(char* fieldName, float& fieldValue) 187 | { 188 | try { 189 | _variant_t vtValue; 190 | vtValue = record_->Fields->GetItem(fieldName)->GetValue(); 191 | fieldValue = vtValue.fltVal; 192 | return true; 193 | } 194 | catch (_com_error &e) { 195 | this->errorReport(e); 196 | SLog(L"! error query field : %S", fieldName); 197 | } 198 | return false; 199 | } 200 | 201 | bool QueryRecord::get(char* fieldName, double& fieldValue) 202 | { 203 | try { 204 | _variant_t vtValue; 205 | vtValue = record_->Fields->GetItem(fieldName)->GetValue(); 206 | fieldValue = vtValue.dblVal; 207 | return true; 208 | } 209 | catch (_com_error &e) { 210 | this->errorReport(e); 211 | SLog(L"! error query field : %S", fieldName); 212 | } 213 | return false; 214 | } 215 | 216 | bool QueryRecord::get(char* fieldName, long& fieldValue) 217 | { 218 | try { 219 | _variant_t vtValue; 220 | vtValue = record_->Fields->GetItem(fieldName)->GetValue(); 221 | fieldValue = vtValue.lVal; 222 | return true; 223 | } 224 | catch (_com_error &e) { 225 | this->errorReport(e); 226 | SLog(L"! error query field : %S", fieldName); 227 | } 228 | return false; 229 | } -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Database/QueryRecord.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Database/QueryRecord.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Database/QueryStatement.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Database/QueryStatement.cpp -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Database/QueryStatement.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Database/QueryStatement.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Asio/ASIOServer.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #ifdef USE_ASIO 3 | #include "../ASIOServer.h" 4 | #include "../ASIOSession.h" 5 | 6 | ASIOServer::ASIOServer(int maxConnection) 7 | : Server(maxConnection) 8 | , ptrService_(new io_service()) 9 | , ioService_(*ptrService_) 10 | , strand_(ioService_) 11 | { 12 | } 13 | 14 | ASIOServer::~ASIOServer() 15 | { 16 | } 17 | 18 | bool ASIOServer::run() 19 | { 20 | ip::tcp::endpoint endPoint(ip::address::from_string(ip_), port_); 21 | acceptor_ = new ip::tcp::acceptor(ioService_, endPoint); 22 | 23 | this->startAccept(); 24 | 25 | for (int i = 0; i < workerThreadCount_; ++i) { 26 | group_.create_thread(boost::bind(&io_service::run, &ioService_)); 27 | } 28 | return true; 29 | } 30 | 31 | void ASIOServer::startAccept() 32 | { 33 | SLog(L"* startAccept..."); 34 | 35 | ASIOSession *session = new ASIOSession(acceptor_->get_io_service(), this->clientManager()); 36 | acceptor_->async_accept(session->socket(), 37 | boost::bind(&ASIOServer::onAccept, 38 | this, 39 | session, 40 | boost::asio::placeholders::error)); 41 | 42 | if (!clientManager_->addSession(session)) { 43 | SLog(L"! maxConnection"); 44 | } 45 | } 46 | 47 | void ASIOServer::onAccept(Session *session, const system::error_code &error) 48 | { 49 | if (error) { 50 | return; 51 | } 52 | 53 | if (!this->clientManager()->addSession(session)) { 54 | return; 55 | } 56 | SLog(L"* client accepted"); 57 | session->recvStandBy(); 58 | } 59 | #endif //USE_ASIO -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Asio/ASIOServer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | #ifdef USE_ASIO 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "../Server.h" 9 | 10 | using namespace std; 11 | using namespace boost; 12 | using namespace boost::asio; 13 | 14 | class ASIOServer : public Server, public Singleton 15 | { 16 | std::shared_ptr ptrService_; 17 | io_service &ioService_; 18 | ip::tcp::acceptor *acceptor_; 19 | 20 | strand strand_; 21 | thread_group group_; 22 | 23 | int seqNumber_; 24 | 25 | public: 26 | ASIOServer(int maxConnection); 27 | virtual ~ASIOServer(); 28 | 29 | bool run(); 30 | 31 | private: 32 | void startAccept(); 33 | void onAccept(Session *session, const system::error_code &error); 34 | }; 35 | #endif //USE_ASIO -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Asio/ASIOSession.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Net/Asio/ASIOSession.cpp -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Asio/ASIOSession.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | #ifdef USE_ASIO 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | class Session; 12 | class SessionManager; 13 | 14 | using namespace std; 15 | using namespace boost; 16 | using namespace boost::asio; 17 | 18 | class ASIOSession : public Session 19 | { 20 | ip::tcp::socket socket_; 21 | str_t writeMessage_; 22 | std::array receiveBuffer_; 23 | 24 | public: 25 | ASIOSession(io_service &ioService, SessionManager* clientManager); 26 | ip::tcp::socket &socket(); 27 | 28 | void sendPacket(char *packet, int len); 29 | private: 30 | void recvStandBy(); 31 | 32 | void onSend(size_t transferSize) 33 | { 34 | } 35 | void onRecv(size_t transferSize) 36 | { 37 | } 38 | 39 | void onSend(size_t transferSize, const boost::system::error_code &error); 40 | void onRecv(size_t transferSize, const boost::system::error_code &error); 41 | 42 | template 43 | void async_write(const T& t, Handler handler); 44 | }; 45 | #endif //USE_ASIO -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Iocp/IOCPServer.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "IOCPServer.h" 3 | #include "IOCPSession.h" 4 | 5 | IOCPServer::IOCPServer(ContentsProcess *contentsProcess) 6 | :Server(contentsProcess) 7 | { 8 | } 9 | 10 | IOCPServer::~IOCPServer() 11 | { 12 | ::closesocket(listenSocket_); 13 | } 14 | 15 | bool IOCPServer::createListenSocket() 16 | { 17 | listenSocket_ = WSASocket(AF_INET, SOCK_STREAM, NULL, NULL, 0, WSA_FLAG_OVERLAPPED); 18 | if (listenSocket_ == INVALID_SOCKET) { 19 | SErrLog(L"! listenSocket fail"); 20 | return false; 21 | } 22 | 23 | SOCKADDR_IN serverAddr; 24 | serverAddr.sin_family = AF_INET; 25 | serverAddr.sin_port = htons((u_short)port_); 26 | inet_pton(AF_INET, ip_, &(serverAddr.sin_addr)); 27 | 28 | int reUseAddr = 1; 29 | setsockopt(listenSocket_, SOL_SOCKET, SO_REUSEADDR, (char *)&reUseAddr, (int)sizeof(reUseAddr)); 30 | 31 | int retval = ::bind(listenSocket_, (SOCKADDR *)&serverAddr, sizeof(serverAddr)); 32 | if (retval == SOCKET_ERROR) { 33 | SErrLog(L"! bind fail"); 34 | return false; 35 | } 36 | 37 | const int BACK_SOCKETS = 5; 38 | retval = ::listen(listenSocket_, BACK_SOCKETS); 39 | if (retval == SOCKET_ERROR) { 40 | SErrLog(L"! listen fail"); 41 | return false; 42 | } 43 | 44 | array ip; 45 | inet_ntop(AF_INET, &(serverAddr.sin_addr), ip.data(), ip.size()); 46 | SLog(L"* server listen socket created, ip: %S, port: %d", ip.data(), port_); 47 | return true; 48 | } 49 | 50 | bool IOCPServer::run() 51 | { 52 | if (MAX_IOCP_THREAD < workerThreadCount_) { 53 | SErrLog(L"! workerThread limit[%d], but config setting [%d]", MAX_IOCP_THREAD, workerThreadCount_); 54 | return false; 55 | } 56 | 57 | iocp_ = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, workerThreadCount_); 58 | if (iocp_ == nullptr) { 59 | return false; 60 | } 61 | this->createListenSocket(); 62 | 63 | acceptThread_ = MAKE_THREAD(IOCPServer, acceptThread); 64 | for (int i = 0; i < workerThreadCount_; ++i) { 65 | workerThread_[i] = MAKE_THREAD(IOCPServer, workerThread); 66 | } 67 | this->status_ = SERVER_READY; 68 | 69 | while (!_shutdown) { 70 | wstring cmdLine; 71 | std::getline(std::wcin, cmdLine); 72 | 73 | SLog(L"Input was: %s", cmdLine.c_str()); 74 | _session_manager.runCommand(cmdLine); 75 | } 76 | return true; 77 | } 78 | 79 | SOCKET IOCPServer::listenSocket() 80 | { 81 | return listenSocket_; 82 | } 83 | 84 | HANDLE IOCPServer::iocp() 85 | { 86 | return iocp_; 87 | } 88 | 89 | void IOCPServer::onAccept(SOCKET accepter, SOCKADDR_IN addrInfo) 90 | { 91 | IOCPSession *session = new IOCPSession(); 92 | if (session == nullptr) { 93 | SLog(L"! accept session create fail"); 94 | return; 95 | } 96 | if (!session->onAccept(accepter, addrInfo)) { 97 | SAFE_DELETE(session); 98 | return; 99 | } 100 | if (!_session_manager.addSession(session)) { 101 | SAFE_DELETE(session); 102 | return; 103 | } 104 | session->ioData_[IO_READ].clear(); 105 | 106 | HANDLE handle = CreateIoCompletionPort((HANDLE)accepter, this->iocp(), (ULONG_PTR)&(*session), NULL); 107 | if (!handle) { 108 | SAFE_DELETE(session); 109 | return; 110 | } 111 | 112 | SLog(L"* client accecpt from [%s]", session->clientAddress().c_str()); 113 | session->recvStandBy(); 114 | } 115 | 116 | DWORD WINAPI IOCPServer::acceptThread(LPVOID serverPtr) 117 | { 118 | IOCPServer *server = (IOCPServer *)serverPtr; 119 | 120 | while (!_shutdown) { 121 | SOCKET acceptSocket = INVALID_SOCKET; 122 | SOCKADDR_IN recvAddr; 123 | static int addrLen = sizeof(recvAddr); 124 | acceptSocket = WSAAccept(server->listenSocket(), (struct sockaddr *)&recvAddr, &addrLen, NULL, 0); 125 | if (acceptSocket == SOCKET_ERROR) { 126 | if (!server->status() == SERVER_STOP) { 127 | SLog(L"! Accept fail"); 128 | break; 129 | } 130 | } 131 | server->onAccept(acceptSocket, recvAddr); 132 | 133 | if (server->status() != SERVER_READY) { 134 | break; 135 | } 136 | } 137 | return 0; 138 | } 139 | 140 | DWORD WINAPI IOCPServer::workerThread(LPVOID serverPtr) 141 | { 142 | IOCPServer *server = (IOCPServer *)serverPtr; 143 | 144 | while (!_shutdown) { 145 | IoData *ioData = nullptr; 146 | IOCPSession *session = nullptr; 147 | DWORD transferSize; 148 | 149 | BOOL ret = GetQueuedCompletionStatus(server->iocp(), &transferSize, (PULONG_PTR)&session, (LPOVERLAPPED *)&ioData, INFINITE); 150 | if (!ret) { 151 | continue; 152 | } 153 | if (session == nullptr) { 154 | SLog(L"! socket data broken"); 155 | return 0; 156 | } 157 | if (transferSize == 0) { 158 | SLog(L"* close by client[%d][%s]", session->id(), session->clientAddress().c_str()); 159 | _session_manager.closeSession(session); 160 | continue; 161 | } 162 | 163 | switch (ioData->type()) { 164 | case IO_WRITE: 165 | session->onSend((size_t)transferSize); 166 | continue; 167 | 168 | case IO_READ: 169 | { 170 | Package *package = session->onRecv((size_t)transferSize); 171 | if (package != nullptr) { 172 | server->putPackage(package); 173 | } 174 | } 175 | continue; 176 | 177 | case IO_ERROR: 178 | SLog(L"* close by client error [%d][%s]", session->id(), session->clientAddress().c_str()); 179 | _session_manager.closeSession(session); 180 | continue; 181 | } 182 | } 183 | return 0; 184 | } 185 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Iocp/IOCPServer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | #include "../Server.h" 4 | 5 | #define MAX_IOCP_THREAD SIZE_64 6 | 7 | class IOCPServer : public Server, public Singleton 8 | { 9 | SOCKET listenSocket_; 10 | HANDLE iocp_; 11 | Thread *acceptThread_; 12 | array workerThread_; 13 | 14 | private: 15 | bool createListenSocket(); 16 | 17 | static DWORD WINAPI acceptThread(LPVOID serverPtr); 18 | static DWORD WINAPI workerThread(LPVOID serverPtr); 19 | 20 | public: 21 | IOCPServer(ContentsProcess *contentsProcess); 22 | virtual ~IOCPServer(); 23 | 24 | bool run(); 25 | 26 | SOCKET listenSocket(); 27 | HANDLE iocp(); 28 | void onAccept(SOCKET accepter, SOCKADDR_IN addrInfo); 29 | }; 30 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Iocp/IOCPSession.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "../Session.h" 3 | #include "IOCPSession.h" 4 | #include "../SessionManager.h" 5 | #include "../Packet/PacketAnalyzer.h" 6 | 7 | IoData::IoData() 8 | { 9 | ZeroMemory(&overlapped_, sizeof(overlapped_)); 10 | ioType_ = IO_ERROR; 11 | 12 | this->clear(); 13 | } 14 | 15 | void IoData::clear() 16 | { 17 | buffer_.fill(0); 18 | totalBytes_ = 0; 19 | currentBytes_ = 0; 20 | } 21 | 22 | bool IoData::needMoreIO(size_t transferSize) 23 | { 24 | currentBytes_ += transferSize; 25 | if (currentBytes_ < totalBytes_) { 26 | return true; 27 | } 28 | return false; 29 | } 30 | 31 | int32_t IoData::setupTotalBytes() 32 | { 33 | packet_size_t offset = 0; 34 | packet_size_t packetLen[1] = { 0, }; 35 | if (totalBytes_ == 0) { 36 | memcpy_s((void *)packetLen, sizeof(packetLen), (void *)buffer_.data(), sizeof(packetLen)); 37 | PacketObfuscation::getInstance().decodingHeader((Byte*)&packetLen, sizeof(packetLen)); 38 | 39 | totalBytes_ = (size_t)packetLen[0]; 40 | } 41 | offset += sizeof(packetLen); 42 | 43 | return offset; 44 | } 45 | size_t IoData::totalByte() 46 | { 47 | return totalBytes_; 48 | } 49 | 50 | IO_OPERATION &IoData::type() 51 | { 52 | return ioType_; 53 | } 54 | 55 | void IoData::setType(IO_OPERATION type) 56 | { 57 | ioType_ = type; 58 | } 59 | 60 | char* IoData::data() 61 | { 62 | return buffer_.data(); 63 | } 64 | 65 | bool IoData::setData(Stream &stream) 66 | { 67 | this->clear(); 68 | 69 | if (buffer_.max_size() <= stream.size()) { 70 | SLog(L"! packet size too big [%d]byte", stream.size()); 71 | return false; 72 | } 73 | 74 | const size_t packetHeaderSize = sizeof(packet_size_t); 75 | packet_size_t offset = 0; 76 | 77 | char *buf = buffer_.data(); 78 | // head size + real data size 79 | packet_size_t packetLen[1] = { (packet_size_t)packetHeaderSize + (packet_size_t)stream.size(), }; 80 | // insert packet len 81 | memcpy_s(buf + offset, buffer_.max_size(), (void *)packetLen, packetHeaderSize); 82 | offset += packetHeaderSize; 83 | 84 | // packet obfuscation 85 | PacketObfuscation::getInstance().encodingHeader((Byte*)buf, packetHeaderSize); 86 | PacketObfuscation::getInstance().encodingData((Byte*)stream.data(), stream.size()); 87 | 88 | // insert packet data 89 | memcpy_s(buf + offset, buffer_.max_size(), stream.data(), (int32_t)stream.size()); 90 | offset += (packet_size_t)stream.size(); 91 | 92 | totalBytes_ = offset; 93 | return true; 94 | } 95 | 96 | LPWSAOVERLAPPED IoData::overlapped() 97 | { 98 | return &overlapped_; 99 | } 100 | 101 | WSABUF IoData::wsabuf() 102 | { 103 | WSABUF wsaBuf; 104 | wsaBuf.buf = buffer_.data() + currentBytes_; 105 | wsaBuf.len = (ULONG)(totalBytes_ - currentBytes_); 106 | return wsaBuf; 107 | } 108 | 109 | //-----------------------------------------------------------------// 110 | IOCPSession::IOCPSession() 111 | : Session() 112 | { 113 | this->initialize(); 114 | } 115 | 116 | void IOCPSession::initialize() 117 | { 118 | ZeroMemory(&socketData_, sizeof(SOCKET_DATA)); 119 | ioData_[IO_READ].setType(IO_READ); 120 | ioData_[IO_WRITE].setType(IO_WRITE); 121 | } 122 | 123 | void IOCPSession::checkErrorIO(DWORD ret) 124 | { 125 | if (ret == SOCKET_ERROR 126 | && (WSAGetLastError() != ERROR_IO_PENDING)) { 127 | SLog(L"! socket error: %d", WSAGetLastError()); 128 | } 129 | } 130 | 131 | void IOCPSession::recv(WSABUF wsaBuf) 132 | { 133 | DWORD flags = 0; 134 | DWORD recvBytes; 135 | DWORD errorCode = WSARecv(socketData_.socket_, &wsaBuf, 1, &recvBytes, &flags, ioData_[IO_READ].overlapped(), NULL); 136 | this->checkErrorIO(errorCode); 137 | } 138 | 139 | bool IOCPSession::isRecving(size_t transferSize) 140 | { 141 | if (ioData_[IO_READ].needMoreIO(transferSize)) { 142 | this->recv(ioData_[IO_READ].wsabuf()); 143 | return true; 144 | } 145 | return false; 146 | } 147 | 148 | void IOCPSession::recvStandBy() 149 | { 150 | ioData_[IO_READ].clear(); 151 | 152 | WSABUF wsaBuf; 153 | wsaBuf.buf = ioData_[IO_READ].data(); 154 | wsaBuf.len = SOCKET_BUF_SIZE; 155 | 156 | this->recv(wsaBuf); 157 | } 158 | 159 | void IOCPSession::send(WSABUF wsaBuf) 160 | { 161 | DWORD flags = 0; 162 | DWORD sendBytes; 163 | DWORD errorCode = WSASend(socketData_.socket_, &wsaBuf, 1, &sendBytes, flags, ioData_[IO_WRITE].overlapped(), NULL); 164 | this->checkErrorIO(errorCode); 165 | } 166 | 167 | void IOCPSession::onSend(size_t transferSize) 168 | { 169 | if (ioData_[IO_WRITE].needMoreIO(transferSize)) { 170 | this->send(ioData_[IO_WRITE].wsabuf()); 171 | } 172 | } 173 | 174 | void IOCPSession::sendPacket(Packet *packet) 175 | { 176 | Stream stream; 177 | packet->encode(stream); 178 | if (!ioData_[IO_WRITE].setData(stream)) { 179 | return; 180 | } 181 | 182 | WSABUF wsaBuf; 183 | wsaBuf.buf = ioData_[IO_WRITE].data(); 184 | wsaBuf.len = (ULONG) stream.size(); 185 | 186 | this->send(wsaBuf); 187 | this->recvStandBy(); 188 | } 189 | 190 | Package *IOCPSession::onRecv(size_t transferSize) 191 | { 192 | packet_size_t offset = 0; 193 | offset += ioData_[IO_READ].setupTotalBytes(); 194 | 195 | if (this->isRecving(transferSize)) { 196 | return nullptr; 197 | } 198 | 199 | const size_t packetHeaderSize = sizeof(packet_size_t); 200 | packet_size_t packetDataSize = (packet_size_t)(ioData_[IO_READ].totalByte() - packetHeaderSize); 201 | Byte *packetData = (Byte*) ioData_[IO_READ].data() + offset; 202 | 203 | PacketObfuscation::getInstance().decodingData(packetData, packetDataSize); 204 | Packet *packet = PacketAnalyzer::getInstance().analyzer((const char *)packetData, packetDataSize); 205 | if (packet == nullptr) { 206 | SLog(L"! invaild packet"); 207 | this->onClose(true); 208 | return nullptr; 209 | } 210 | 211 | this->recvStandBy(); 212 | 213 | Package *package = new Package(this, packet); 214 | return package; 215 | } 216 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Iocp/IOCPSession.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | class Session; 4 | class SessionManager; 5 | class Package; 6 | 7 | typedef enum { 8 | IO_READ, 9 | IO_WRITE, 10 | IO_ERROR, 11 | } IO_OPERATION; 12 | #define IO_DATA_MAX (2) 13 | 14 | class IoData 15 | { 16 | OVERLAPPED overlapped_; 17 | IO_OPERATION ioType_; 18 | size_t totalBytes_; 19 | size_t currentBytes_; 20 | array buffer_; 21 | 22 | public: 23 | IoData(); 24 | 25 | void clear(); 26 | 27 | bool needMoreIO(size_t transferSize); 28 | int32_t setupTotalBytes(); 29 | size_t totalByte(); 30 | 31 | IO_OPERATION &type(); 32 | void setType(IO_OPERATION type); 33 | 34 | WSABUF wsabuf(); 35 | char *data(); 36 | bool setData(Stream &stream); 37 | LPWSAOVERLAPPED overlapped(); 38 | }; 39 | 40 | //-----------------------------------------------------------------// 41 | class IOCPSession : public Session 42 | { 43 | public: 44 | array ioData_; 45 | 46 | private: 47 | void initialize(); 48 | 49 | void checkErrorIO(DWORD ret); 50 | 51 | void recv(WSABUF wsaBuf); 52 | bool isRecving(size_t transferSize); 53 | 54 | void send(WSABUF wsaBuf); 55 | 56 | public: 57 | IOCPSession(); 58 | 59 | void onSend(size_t transferSize); 60 | void sendPacket(Packet *packet); 61 | 62 | Package* onRecv(size_t transferSize); 63 | void recvStandBy(); 64 | 65 | }; 66 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Packet.h: -------------------------------------------------------------------------------- 1 | #include "packetHeader.h" 2 | #include "Stream.h" 3 | 4 | struct Packet { 5 | void encode(Stream &stream) {} 6 | void decode(Stream &stream) {} 7 | }; 8 | 9 | struct PK_C_REQ_ID_PW : Packet 10 | { 11 | int packetType() { return E_C_REQ_ID_PW; } 12 | std::string id; 13 | std::string password; 14 | 15 | void encode(Stream &stream) { 16 | stream << id; 17 | stream << password; 18 | } 19 | 20 | void decode(Stream &stream) { 21 | stream >> &id; 22 | stream >> &password; 23 | } 24 | }; 25 | 26 | struct PK_S_REQ_ID_ID_PW : Packet 27 | { 28 | int packetType() { return E_S_REQ_ID_ID_PW; } 29 | bool result; 30 | 31 | void encode(Stream &stream) { 32 | stream << result; 33 | } 34 | 35 | void decode(Stream &stream) { 36 | stream >> &result; 37 | } 38 | }; 39 | 40 | struct PK_C_NOTIFY_HEARTBEET : Packet 41 | { 42 | int packetType() { return E_C_NOTIFY_HEARTBEET; } 43 | }; 44 | 45 | struct PK_C_REQ_CHATTING : Packet 46 | { 47 | int packetType() { return E_C_REQ_CHATTING; } 48 | std::string text; 49 | 50 | void encode(Stream &stream) { 51 | stream << text; 52 | } 53 | 54 | void decode(Stream &stream) { 55 | stream >> &text; 56 | } 57 | }; 58 | 59 | struct PK_S_REQ_CHATTING : Packet 60 | { 61 | int packetType() { return E_S_REQ_CHATTING; } 62 | std::string id; 63 | std::string text; 64 | 65 | void encode(Stream &stream) { 66 | stream << id; 67 | stream << text; 68 | } 69 | 70 | void decode(Stream &stream) { 71 | stream >> &id; 72 | stream >> &text; 73 | } 74 | }; 75 | 76 | 77 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Packet/Package.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | class Session; 5 | class Package 6 | { 7 | public: 8 | Session *session_; 9 | Packet *packet_; 10 | 11 | Package(Session *session, Packet *packet) 12 | { 13 | session_ = session; 14 | packet_ = packet; 15 | } 16 | 17 | ~Package() 18 | { 19 | session_ = nullptr; 20 | SAFE_DELETE(packet_); 21 | } 22 | }; -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Packet/PacketAnalyzer.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | #include "PacketClass.h" 4 | #include "PacketAnalyzer.h" 5 | #include "PacketFactory.h" 6 | 7 | Packet* PacketAnalyzer::analyzer(const char *rowPacket, size_t size) 8 | { 9 | size_t offset = 0; 10 | PacketType type[1] = { (PacketType)0, }; 11 | memcpy_s((void *)type, sizeof(type), (void *)rowPacket, sizeof(type)); 12 | offset += sizeof(type); 13 | 14 | Packet *packet = _packet_factory.getPacket(type[0]); 15 | if (packet) { 16 | if (offset < size) { 17 | Stream stream((UCHAR *)(rowPacket + offset), size - offset); 18 | packet->decode(stream); 19 | } 20 | } 21 | 22 | return packet; 23 | } -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Packet/PacketAnalyzer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | class PacketAnalyzer : public Singleton < PacketAnalyzer > 5 | { 6 | public: 7 | Packet* analyzer(const char *rowPacket, size_t size); 8 | }; -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Packet/PacketFactory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | #include "packetHeader.h" 4 | #include "packetClass.h" 5 | 6 | #define _packet_factory PacketFactory::getInstance() 7 | 8 | class PacketFactory : public Singleton 9 | { 10 | public: 11 | Packet* getPacket(Int64 packetType) 12 | { 13 | switch (packetType) { 14 | case E_C_REQ_EXIT: return new PK_C_REQ_EXIT(); 15 | case E_S_ANS_EXIT: return new PK_S_ANS_EXIT(); 16 | case E_I_NOTIFY_TERMINAL: return new PK_I_NOTIFY_TERMINAL(); 17 | case E_C_NOTIFY_HEARTBEAT: return new PK_C_NOTIFY_HEARTBEAT(); 18 | case E_C_REQ_ID_PW: return new PK_C_REQ_ID_PW(); 19 | case E_S_ANS_ID_PW_FAIL: return new PK_S_ANS_ID_PW_FAIL(); 20 | case E_S_ANS_ID_PW_SUCCESS: return new PK_S_ANS_ID_PW_SUCCESS(); 21 | case E_I_DB_REQ_ID_PW: return new PK_I_DB_REQ_ID_PW(); 22 | case E_I_DB_ANS_ID_PW: return new PK_I_DB_ANS_ID_PW(); 23 | case E_I_CHTTING_NOTIFY_ID: return new PK_I_CHTTING_NOTIFY_ID(); 24 | case E_I_DB_REQ_LOAD_DATA: return new PK_I_DB_REQ_LOAD_DATA(); 25 | case E_I_DB_ANS_PARSE_DATA: return new PK_I_DB_ANS_PARSE_DATA(); 26 | case E_I_LOGIN_NOTIFY_ID_LOADED: return new PK_I_LOGIN_NOTIFY_ID_LOADED(); 27 | case E_C_REQ_REGIST_CHATTING_NAME: return new PK_C_REQ_REGIST_CHATTING_NAME(); 28 | case E_C_REQ_CHATTING: return new PK_C_REQ_CHATTING(); 29 | case E_S_ANS_CHATTING: return new PK_S_ANS_CHATTING(); 30 | } 31 | return nullptr; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Packet/PacketHeader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | #define PACKET_MAKE_DATE "2015/03/14 13:14:41" 5 | enum PacketType : Int64 { 6 | /*128*/ E_C_REQ_EXIT = 128, 7 | /*129*/ E_S_ANS_EXIT = 129, 8 | /*130*/ E_I_NOTIFY_TERMINAL = 130, 9 | /*131*/ E_C_NOTIFY_HEARTBEAT = 131, 10 | /*132*/ E_C_REQ_ID_PW = 132, 11 | /*133*/ E_S_ANS_ID_PW_FAIL = 133, 12 | /*134*/ E_S_ANS_ID_PW_SUCCESS = 134, 13 | /*135*/ E_I_DB_REQ_ID_PW = 135, 14 | /*136*/ E_I_DB_ANS_ID_PW = 136, 15 | /*137*/ E_I_CHTTING_NOTIFY_ID = 137, 16 | /*138*/ E_I_DB_REQ_LOAD_DATA = 138, 17 | /*139*/ E_I_DB_ANS_PARSE_DATA = 139, 18 | /*140*/ E_I_LOGIN_NOTIFY_ID_LOADED = 140, 19 | /*141*/ E_C_REQ_REGIST_CHATTING_NAME = 141, 20 | /*142*/ E_C_REQ_CHATTING = 142, 21 | /*143*/ E_S_ANS_CHATTING = 143, 22 | }; 23 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Packet/PacketObfuscation.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Net/Packet/PacketObfuscation.cpp -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Packet/PacketObfuscation.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Net/Packet/PacketObfuscation.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Packet/Stream.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | #include "Stream.h" 4 | 5 | Stream::Stream() 6 | { 7 | this->initialize(); 8 | } 9 | 10 | Stream::Stream(UCHAR *stream, size_t size) 11 | { 12 | this->initialize(); 13 | this->set(stream, size); 14 | } 15 | 16 | void Stream::initialize() 17 | { 18 | readPt_ = 0; 19 | offset_ = 0; 20 | ZeroMemory(&stream_, sizeof(stream_)); 21 | } 22 | 23 | UCHAR *Stream::data() 24 | { 25 | return stream_.data(); 26 | } 27 | 28 | size_t Stream::size() 29 | { 30 | return offset_; 31 | } 32 | 33 | void Stream::operator = (Stream &stream) 34 | { 35 | this->set(stream.data(), stream.size()); 36 | } 37 | 38 | void Stream::set(UCHAR *data, size_t size) 39 | { 40 | this->offset_ = size; 41 | memcpy_s(this->stream_.data(), stream_.size(), (void *)data, size); 42 | } 43 | 44 | // write 45 | //------------------------------------------------------------------------// 46 | bool Stream::checkWriteBound(size_t len) 47 | { 48 | if (offset_ + len > sizeof(stream_)) { 49 | SLog(L"! socket stream over."); 50 | ASSERT(FALSE); 51 | return false; 52 | } 53 | return true; 54 | } 55 | 56 | #define STREAM_WRITE(value) \ 57 | INT32 size = sizeof(value); \ 58 | if (this->checkWriteBound(size) == false) { \ 59 | return; \ 60 | } \ 61 | memcpy_s((void *)(stream_.data() + offset_), stream_.size() - offset_, (const void *)&value, size);\ 62 | offset_ += size; 63 | 64 | template 65 | void Stream::operator << (const T &value) 66 | { 67 | STREAM_WRITE(value); 68 | } 69 | void Stream::operator << (const bool &value) 70 | { 71 | STREAM_WRITE(value); 72 | } 73 | void Stream::operator << (const INT8 &value) 74 | { 75 | STREAM_WRITE(value); 76 | } 77 | void Stream::operator << (const UINT8 &value) 78 | { 79 | STREAM_WRITE(value); 80 | } 81 | void Stream::operator << (const INT16 &value) 82 | { 83 | STREAM_WRITE(value); 84 | } 85 | void Stream::operator << (const UINT16 &value) 86 | { 87 | STREAM_WRITE(value); 88 | } 89 | void Stream::operator << (const INT32 &value) 90 | { 91 | STREAM_WRITE(value); 92 | } 93 | void Stream::operator << (const UINT32 &value) 94 | { 95 | STREAM_WRITE(value); 96 | } 97 | void Stream::operator << (const INT64 &value) 98 | { 99 | STREAM_WRITE(value); 100 | } 101 | void Stream::operator << (const UINT64 &value) 102 | { 103 | STREAM_WRITE(value); 104 | } 105 | 106 | void Stream::operator << (const std::vector &value) 107 | { 108 | *this << value.size(); 109 | for (auto i : value) { 110 | *this << i; 111 | } 112 | } 113 | 114 | void Stream::operator << (const str_t value) 115 | { 116 | *this << (Int32)value.length(); 117 | for (auto i : value) { 118 | *this << i; 119 | } 120 | } 121 | 122 | void Stream::operator << (const wstr_t value) 123 | { 124 | *this << (Int32)(value.length()); 125 | for (auto i : value) { 126 | *this << i; 127 | } 128 | } 129 | 130 | // read 131 | //------------------------------------------------------------------------// 132 | bool Stream::checkReadBound(size_t len) 133 | { 134 | if (readPt_ + len > offset_) { 135 | SLog(L"! readOffset : %d, size: %d, totalOffset = %d", readPt_, len, offset_); 136 | SLog(L"! socket stream has not more memory."); 137 | ASSERT(FALSE); 138 | return false; 139 | } 140 | return true; 141 | } 142 | 143 | void Stream::read(void *retVal, size_t len) 144 | { 145 | memcpy_s(retVal, len, (void *)(stream_.data() + readPt_), len); 146 | readPt_ += len; 147 | } 148 | 149 | #define STREAM_READ(type, retVal) \ 150 | size_t size = sizeof(type); \ 151 | if (this->checkReadBound(size) == false) { \ 152 | return; \ 153 | } \ 154 | this->read((void *)(retVal), size); 155 | 156 | template 157 | void Stream::operator >> (T *retVal) 158 | { 159 | STREAM_READ(T, retVal); 160 | } 161 | 162 | void Stream::operator >> (bool *retVal) 163 | { 164 | STREAM_READ(bool, retVal); 165 | } 166 | void Stream::operator >> (INT8 *retVal) 167 | { 168 | STREAM_READ(INT8, retVal); 169 | } 170 | void Stream::operator >> (UINT8 *retVal) 171 | { 172 | STREAM_READ(UINT8, retVal); 173 | } 174 | void Stream::operator >> (INT16 *retVal) 175 | { 176 | STREAM_READ(INT16, retVal); 177 | } 178 | void Stream::operator >> (UINT16 *retVal) 179 | { 180 | STREAM_READ(UINT16, retVal); 181 | } 182 | void Stream::operator >> (INT32 *retVal) 183 | { 184 | STREAM_READ(INT32, retVal); 185 | } 186 | void Stream::operator >> (UINT32 *retVal) 187 | { 188 | STREAM_READ(UINT32, retVal); 189 | } 190 | void Stream::operator >> (INT64 *retVal) 191 | { 192 | STREAM_READ(INT64, retVal); 193 | } 194 | void Stream::operator >> (UINT64 *retVal) 195 | { 196 | STREAM_READ(UINT64, retVal); 197 | } 198 | 199 | void Stream::operator >> (std::vector *retVal) 200 | { 201 | size_t size; 202 | *this >> &size; 203 | 204 | for (size_t i = 0; i < size; ++i) { 205 | wstr_t tmp; 206 | *this >> &tmp; 207 | retVal->push_back(tmp); 208 | } 209 | } 210 | 211 | void Stream::operator >> (str_t *retVal) 212 | { 213 | INT32 size; 214 | *this >> &size; 215 | if (this->checkReadBound(size) == false) { 216 | return; 217 | } 218 | 219 | char *buf = new char[size + 1]; 220 | this->read((void *)(buf), size * sizeof(CHAR)); 221 | buf[size] = '\0'; 222 | 223 | retVal->clear(); 224 | *retVal = buf; 225 | 226 | delete buf; 227 | } 228 | 229 | void Stream::operator >> (wstr_t *retVal) 230 | { 231 | INT32 size; 232 | *this >> &size; 233 | if (this->checkReadBound(size) == false) { 234 | return; 235 | } 236 | 237 | WCHAR *buf = new WCHAR[size + 1]; 238 | this->read((void *)(buf), size * sizeof(WCHAR)); 239 | buf[size] = '\0'; 240 | 241 | retVal->clear(); 242 | *retVal = buf; 243 | 244 | delete buf; 245 | } -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Packet/Stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | class Stream 5 | { 6 | size_t offset_; 7 | size_t readPt_; 8 | array stream_; 9 | 10 | public: 11 | Stream(); 12 | Stream(UCHAR *stream, size_t size); 13 | void initialize(); 14 | 15 | UCHAR *data(); 16 | size_t size(); 17 | 18 | void operator = (Stream &stream); 19 | void set(UCHAR *stream, size_t size); 20 | 21 | // write 22 | //------------------------------------------------------------------------// 23 | bool checkWriteBound(size_t len); 24 | 25 | 26 | template 27 | void operator << (const T &value); 28 | void operator << (const bool &value); 29 | void operator << (const INT8 &value); 30 | void operator << (const UINT8 &value); 31 | void operator << (const INT16 &value); 32 | void operator << (const UINT16 &value); 33 | void operator << (const INT32 &value); 34 | void operator << (const UINT32 &value); 35 | void operator << (const INT64 &value); 36 | void operator << (const UINT64 &value); 37 | 38 | void operator << (const std::vector &value); 39 | 40 | void operator << (const str_t value); 41 | void operator << (const wstr_t value); 42 | 43 | // read 44 | //------------------------------------------------------------------------// 45 | bool checkReadBound(size_t len); 46 | void read(void *retVal, size_t len); 47 | 48 | template 49 | void operator >> (T *retVal); 50 | 51 | void operator >> (bool *retVal); 52 | void operator >> (INT8 *retVal); 53 | void operator >> (UINT8 *retVal); 54 | void operator >> (INT16 *retVal); 55 | void operator >> (UINT16 *retVal); 56 | void operator >> (INT32 *retVal); 57 | void operator >> (UINT32 *retVal); 58 | void operator >> (INT64 *retVal); 59 | void operator >> (UINT64 *retVal); 60 | 61 | void operator >> (std::vector *retVal); 62 | 63 | void operator >> (str_t *retVal); 64 | void operator >> (wstr_t *retVal); 65 | }; -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/PacketHeader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../stdafx.h" 3 | 4 | enum EPacket { 5 | /*0*/ E_C_REQ_ID_PW, 6 | /*1*/ E_S_REQ_ID_ID_PW, 7 | /*2*/ E_C_NOTIFY_HEARTBEET, 8 | /*3*/ E_C_REQ_CHATTING, 9 | /*4*/ E_S_REQ_CHATTING, 10 | }; 11 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/PacketManager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Net/PacketManager.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Server.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Net/Server.cpp -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Server.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Net/Server.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Session.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Session.h" 3 | #include "./Iocp/IOCPServer.h" 4 | 5 | Session::Session() 6 | { 7 | type_ = SESSION_TYPE_CLIENT; 8 | this->updateHeartBeat(); 9 | } 10 | 11 | Session::~Session() 12 | { 13 | this->onClose(); 14 | } 15 | 16 | bool Session::setSocketOpt() 17 | { 18 | #ifdef linux 19 | int keepAlive = 1; 20 | int keepAliveIdle = 1; 21 | int keepAliveCnt = 3; 22 | int keepAliveInterval = 3; 23 | 24 | int ret; 25 | ret = ::setsockopt(socketData_.socket_, SOL_SOCKET, SO_KEEPALIVE, &keepAlive, sizeof(keepAlive)); 26 | if (ret == SOCKET_ERROR) { 27 | return false; 28 | } 29 | ret = ::setsockopt(socketData_.socket_, SOL_TCP, SO_KEEPIDLE, &keepAliveIdle, sizeof(keepAliveIdle)); 30 | if (ret == SOCKET_ERROR) { 31 | return false; 32 | } 33 | ret = ::setsockopt(socketData_.socket_, SOL_TCP, SO_KEEPCNT, &keepAliveCnt, sizeof(keepAliveCnt)); 34 | if (ret == SOCKET_ERROR) { 35 | return false; 36 | } 37 | ret = ::setsockopt(socketData_.socket_, SOL_TCP, SO_KEEPINTVL, &keepAliveInterval, sizeof(keepAliveInterval)); 38 | if (ret == SOCKET_ERROR) { 39 | return false; 40 | } 41 | #else 42 | tcp_keepalive keepAliveSet = { 0 }, returned = { 0 }; 43 | keepAliveSet.onoff = 1; 44 | keepAliveSet.keepalivetime = 3000; // Keep Alive in 3 sec. 45 | keepAliveSet.keepaliveinterval = 3000; // Resend if No-Reply 46 | 47 | DWORD dwBytes; 48 | if (WSAIoctl(socketData_.socket_, SIO_KEEPALIVE_VALS, &keepAliveSet, sizeof(keepAliveSet), &returned, sizeof(returned), &dwBytes, NULL, NULL) != 0) { 49 | return false; 50 | } 51 | #endif 52 | return true; 53 | } 54 | 55 | bool Session::onAccept(SOCKET socket, SOCKADDR_IN addrInfo) 56 | { 57 | socketData_.socket_ = socket; 58 | int addrLen; 59 | getpeername(socketData_.socket_, (struct sockaddr *)&socketData_.addrInfo_, &addrLen); 60 | socketData_.addrInfo_ = addrInfo; 61 | if (!this->setSocketOpt()) { 62 | return false; 63 | } 64 | return true; 65 | } 66 | 67 | void Session::onClose(bool force) 68 | { 69 | if (force) { 70 | _session_manager.forceCloseSession(this); 71 | } 72 | else { 73 | _session_manager.closeSession(this); 74 | } 75 | } 76 | 77 | SOCKET& Session::socket() 78 | { 79 | return socketData_.socket_; 80 | } 81 | 82 | wstr_t Session::clientAddress() 83 | { 84 | array ip; 85 | inet_ntop(AF_INET, &(socketData_.addrInfo_.sin_addr), ip.data(), ip.size()); 86 | 87 | array wip; 88 | StrConvA2W(ip.data(), wip.data(), wip.max_size()); 89 | wstr_t stringData = wip.data(); 90 | 91 | return stringData; 92 | } 93 | 94 | oid_t Session::id() 95 | { 96 | return id_; 97 | } 98 | 99 | void Session::setId(oid_t id) 100 | { 101 | id_ = id; 102 | } 103 | 104 | int8_t Session::type() 105 | { 106 | return type_; 107 | } 108 | 109 | void Session::setType(int8_t type) 110 | { 111 | type_ = type; 112 | } 113 | 114 | tick_t Session::heartBeat() 115 | { 116 | return lastHeartBeat_; 117 | } 118 | 119 | void Session::updateHeartBeat() 120 | { 121 | lastHeartBeat_ = CLOCK.systemTick(); 122 | } -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Session.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Net/Session.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/SessionManager.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Net/SessionManager.cpp -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/SessionManager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Net/SessionManager.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/SessionMonitor.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Net/SessionMonitor.cpp -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/SessionMonitor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | class SessionMonitor : public Work 5 | { 6 | public : 7 | SessionMonitor(); 8 | void tick(); 9 | }; 10 | static SessionMonitor sessionMonitor; -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | using namespace std; 4 | 5 | class Stream 6 | { 7 | size_t offset_; 8 | size_t readPt_; 9 | array stream_; 10 | 11 | public: 12 | Stream() 13 | { 14 | readPt_ = 0; 15 | offset_ = 0; 16 | ZeroMemory(&stream_, sizeof(stream_)); 17 | } 18 | 19 | UCHAR *stream() 20 | { 21 | return stream_.data(); 22 | } 23 | 24 | size_t size() 25 | { 26 | return offset_; 27 | } 28 | 29 | void operator = (Stream &stream) 30 | { 31 | this->set(stream.stream(), stream.size()); 32 | } 33 | 34 | void set(UCHAR *stream, size_t size) 35 | { 36 | this->offset_ = size; 37 | memcpy_s(this->stream_.data(), stream_.size(), (void *)stream, size); 38 | } 39 | 40 | // write 41 | //------------------------------------------------------------------------// 42 | bool checkWriteBound(size_t len) 43 | { 44 | if (offset_ + len > sizeof(stream_)) { 45 | SLog(L"! socket stream over."); 46 | ASSERT(FALSE); 47 | return false; 48 | } 49 | return true; 50 | } 51 | 52 | template 53 | void operator << (const T &value) 54 | { 55 | size_t size = sizeof(value); 56 | if (this->checkWriteBound(size) == false) { 57 | return; 58 | } 59 | 60 | memcpy_s((void *)(stream_.data() + offset_), stream_.size() - offset_, (const void *)&value, size); 61 | offset_ += size; 62 | } 63 | 64 | template 65 | void operator << (const std::vector &value) 66 | { 67 | *this << value.size(); 68 | for (auto i : value) { 69 | *this << i; 70 | } 71 | } 72 | 73 | void operator << (std::string value) 74 | { 75 | *this << value.length(); 76 | for (auto i : value) { 77 | *this << i; 78 | } 79 | } 80 | 81 | void operator << (wstr_t value) 82 | { 83 | *this << (value.length()); 84 | for (auto i : value) { 85 | *this << i; 86 | } 87 | } 88 | 89 | // read 90 | //------------------------------------------------------------------------// 91 | bool checkReadBound(size_t len) 92 | { 93 | if (readPt_ + len > offset_) { 94 | SLog(L"! readOffset : %d, size: %d, totalOffset = %d", readPt_, len, offset_); 95 | SLog(L"! socket stream has not more memory."); 96 | ASSERT(FALSE); 97 | return false; 98 | } 99 | return true; 100 | } 101 | 102 | void read(void *retVal, size_t len) 103 | { 104 | memcpy_s(retVal, len, (void *)(stream_.data() + readPt_), len); 105 | readPt_ += len; 106 | } 107 | 108 | template 109 | void operator >> (T *retVal) 110 | { 111 | size_t size = sizeof(*retVal); 112 | if (this->checkReadBound(size) == false) { 113 | return; 114 | } 115 | this->read((void *)(retVal), sizeof(T)); 116 | } 117 | 118 | void operator >> (std::string *retVal) 119 | { 120 | size_t size; 121 | *this >> &size; 122 | if (this->checkReadBound(size) == false) { 123 | return; 124 | } 125 | 126 | char *buf = new char[size + 1]; 127 | this->read((void *)(buf), size * sizeof(CHAR)); 128 | buf[size] = '\0'; 129 | 130 | retVal->clear(); 131 | *retVal = buf; 132 | 133 | delete buf; 134 | } 135 | 136 | void operator >> (wstr_t *retVal) 137 | { 138 | size_t size; 139 | *this >> &size; 140 | if (this->checkReadBound(size) == false) { 141 | return; 142 | } 143 | 144 | WCHAR *buf = new WCHAR[size + 1]; 145 | this->read((void *)(buf), size * sizeof(WCHAR)); 146 | buf[size] = '\0'; 147 | 148 | retVal->clear(); 149 | *retVal = buf; 150 | 151 | delete buf; 152 | } 153 | 154 | template 155 | void operator >> (std::vector *retVal) 156 | { 157 | size_t size; 158 | *this >> &size; 159 | 160 | for (size_t i = 0; i < size; ++i) { 161 | T tmp; 162 | *this >> &tmp; 163 | retVal->push_back(tmp); 164 | } 165 | } 166 | }; -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Terminal/Terminal.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Net/Terminal/Terminal.cpp -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Terminal/Terminal.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Net/Terminal/Terminal.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Terminal/TerminalManager.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | TerminalManager::TerminalManager() 5 | { 6 | } 7 | 8 | TerminalManager::~TerminalManager() 9 | { 10 | for (auto itr : terminalPool_) { 11 | auto terminal = itr.second; 12 | SAFE_DELETE(terminal); 13 | } 14 | } 15 | 16 | void TerminalManager::initialize(xml_t *config) 17 | { 18 | xmlNode_t *root = config->FirstChildElement("App")->FirstChildElement("Terminal"); 19 | xmlHandle_t terminalNode = TiXmlHandle(root); 20 | if (!root) { 21 | SLog(L"@ not exist terminal setting"); 22 | return; 23 | } 24 | 25 | xmlNode_t *elem = terminalNode.FirstChildElement().Element(); 26 | while (elem) { 27 | array terminalName; 28 | StrConvA2W((char *)elem->Value(), terminalName.data(), terminalName.max_size()); 29 | 30 | Terminal *terminal = new Terminal(server_, terminalName.data()); 31 | terminal->initialize(elem); 32 | this->put(terminalName.data(), terminal); 33 | 34 | elem = elem->NextSiblingElement(); 35 | } 36 | 37 | SLog(L"### Terminal set ###"); 38 | } 39 | 40 | void TerminalManager::put(wstr_t serverName, Terminal *terminal) 41 | { 42 | terminalPool_.insert(make_pair(serverName, terminal)); 43 | } 44 | 45 | Terminal* TerminalManager::get(wstr_t name) 46 | { 47 | auto itr = terminalPool_.find(name); 48 | if (itr == terminalPool_.end()) { 49 | return nullptr; 50 | } 51 | return terminalPool_.at(name); 52 | } 53 | 54 | bool TerminalManager::isTerminal(const char *ip) 55 | { 56 | for (auto terminal : terminalPool_) { 57 | if (!strcmp(terminal.second->ip(), ip)) { 58 | return true; 59 | } 60 | } 61 | return false; 62 | } 63 | 64 | void TerminalManager::run(Server *server) 65 | { 66 | server_ = server; 67 | 68 | xml_t config; 69 | if (!loadConfig(&config)) { 70 | return; 71 | } 72 | this->initialize(&config); 73 | } -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Terminal/TerminalManager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Net/Terminal/TerminalManager.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Terminal/TerminalSession.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Net/Terminal/TerminalSession.cpp -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/Terminal/TerminalSession.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | class TerminalSession : public Session 5 | { 6 | public: 7 | bool connectTo(char *ip, int port); 8 | void onSend(size_t transferSize); 9 | void sendPacket(Packet *packet); 10 | 11 | Package* onRecv(size_t transferSize); 12 | }; -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Net/WinSocket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | class WinSocket 5 | { 6 | WSADATA wsa_; 7 | 8 | public: 9 | WinSocket() 10 | { 11 | static bool init = false; 12 | if (init) { 13 | return; 14 | } 15 | 16 | if (WSAStartup(MAKEWORD(2, 2), &wsa_) != 0) { 17 | printf("! wsa startup fail\n"); 18 | exit(0); 19 | } 20 | 21 | init = true; 22 | printf("### WSA 2.2 set complet.\n"); 23 | } 24 | ~WinSocket() 25 | { 26 | WSACleanup(); 27 | } 28 | }; 29 | 30 | static WinSocket winsocket; -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | STATIC LIBRARY : ServerLibrary Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this ServerLibrary library project for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your ServerLibrary application. 9 | 10 | 11 | ServerLibrary.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | ServerLibrary.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | 25 | ///////////////////////////////////////////////////////////////////////////// 26 | 27 | StdAfx.h, StdAfx.cpp 28 | These files are used to build a precompiled header (PCH) file 29 | named ServerLibrary.pch and a precompiled types file named StdAfx.obj. 30 | 31 | ///////////////////////////////////////////////////////////////////////////// 32 | Other notes: 33 | 34 | AppWizard uses "TODO:" comments to indicate parts of the source code you 35 | should add to or customize. 36 | 37 | ///////////////////////////////////////////////////////////////////////////// 38 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/ServerLibrary.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/ServerLibrary.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Shutdown.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Shutdown.cpp -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Shutdown.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | //-------------------------------------------------------------------// 4 | extern bool _shutdown; 5 | extern void shutdownServer(); 6 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Assert.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Assert.h" 3 | 4 | void Assert(int condition, LPCWSTR conditionStr, LPCWSTR fileName, int lineNo) 5 | { 6 | if (condition) { 7 | return; 8 | } 9 | shutdownServer(); 10 | 11 | wstr_t msg; 12 | msg = L" Assert: "; 13 | msg += conditionStr; 14 | msg += L", file : "; 15 | msg += fileName; 16 | msg += L", line : "; 17 | 18 | WCHAR buf[16]; 19 | _itow_s(lineNo, buf, 10); 20 | msg += buf; 21 | SLog(L"! error %s", msg.c_str()); 22 | MiniDump::getInstance().execptionFilter(NULL); 23 | } 24 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Assert.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | #undef ASSERT 5 | #define ASSERT(x) Assert(x, _W(#x), _W(__FILE__), __LINE__) 6 | 7 | void Assert(int condition, LPCWSTR conditionStr, LPCWSTR fileName, int lineNo); 8 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Clock.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/Clock.cpp -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Clock.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/Clock.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Config.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Config.h" 3 | 4 | bool loadConfig(xml_t *config) 5 | { 6 | if (!config->LoadFile("./config.xml")) { 7 | printf("! not exist config file."); 8 | return false; 9 | } 10 | return true; 11 | } 12 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | extern bool loadConfig(xml_t *config); -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/GameObject.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/GameObject.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Lock.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/Lock.cpp -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Lock.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/Lock.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Logger.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/Logger.cpp -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Logger.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/Logger.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/MemoryLeak.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/MemoryLeak.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Memory_LowFragmentationHeap.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/Memory_LowFragmentationHeap.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Minidump.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/Minidump.cpp -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Minidump.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/Minidump.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Monitoring.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | #include "psapi.h" 4 | 5 | class Monitoring : public Singleton 6 | { 7 | ULARGE_INTEGER lastCPU, lastSysCPU, lastUserCPU; 8 | int numProcessors; 9 | HANDLE self; 10 | 11 | public: 12 | Monitoring() 13 | { 14 | SYSTEM_INFO sysInfo; 15 | FILETIME ftime, fsys, fuser; 16 | 17 | GetSystemInfo(&sysInfo); 18 | numProcessors = sysInfo.dwNumberOfProcessors; 19 | 20 | GetSystemTimeAsFileTime(&ftime); 21 | memcpy(&lastCPU, &ftime, sizeof(FILETIME)); 22 | 23 | self = GetCurrentProcess(); 24 | GetProcessTimes(self, &ftime, &ftime, &fsys, &fuser); 25 | memcpy(&lastSysCPU, &fsys, sizeof(FILETIME)); 26 | memcpy(&lastUserCPU, &fuser, sizeof(FILETIME)); 27 | } 28 | 29 | double processCpuUsage() 30 | { 31 | FILETIME ftime, fsys, fuser; 32 | ULARGE_INTEGER now, sys, user; 33 | double percent; 34 | 35 | GetSystemTimeAsFileTime(&ftime); 36 | memcpy(&now, &ftime, sizeof(FILETIME)); 37 | 38 | GetProcessTimes(self, &ftime, &ftime, &fsys, &fuser); 39 | memcpy(&sys, &fsys, sizeof(FILETIME)); 40 | memcpy(&user, &fuser, sizeof(FILETIME)); 41 | percent = (double)((sys.QuadPart - lastSysCPU.QuadPart) + (user.QuadPart - lastUserCPU.QuadPart)); 42 | percent /= (now.QuadPart - lastCPU.QuadPart); 43 | percent /= numProcessors; 44 | // lastCPU = now; 45 | // lastUserCPU = user; 46 | // lastSysCPU = sys; 47 | percent = percent * 100; 48 | return fixInRange(0, percent, 100); 49 | } 50 | 51 | SIZE_T processMemUsage() 52 | { 53 | PROCESS_MEMORY_COUNTERS pmc; 54 | GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)); 55 | return (size_t) pmc.WorkingSetSize; 56 | } 57 | 58 | SIZE_T physyicMemUsage() 59 | { 60 | MEMORYSTATUSEX memInfo; 61 | memInfo.dwLength = sizeof(MEMORYSTATUSEX); 62 | GlobalMemoryStatusEx(&memInfo); 63 | 64 | return (size_t) memInfo.ullTotalPhys - memInfo.ullAvailPhys; 65 | } 66 | }; -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/ProgramValidation.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/ProgramValidation.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/RandomMT.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/RandomMT.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/SMTPMail.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "SMTPMail.h" 3 | 4 | void smtpWriteLine(SOCKET sock, const char *str, const char *arg) 5 | { 6 | array buf; 7 | if (arg != NULL) { 8 | snprintf(buf, str, arg); 9 | } 10 | else { 11 | snprintf(buf, str); 12 | } 13 | 14 | ::send(sock, buf.data(), (int) buf.size(), 0); 15 | } 16 | 17 | bool connectSMTP(SOCKET *sock) 18 | { 19 | *sock = ::socket(AF_INET, SOCK_STREAM, 0); 20 | if (*sock == SOCKET_ERROR) { 21 | SLog(L"! mail socket make fail"); 22 | return false; 23 | } 24 | 25 | const int SMTP_PORT = 25; 26 | struct sockaddr_in serverAddr; 27 | serverAddr.sin_family = AF_INET; 28 | serverAddr.sin_port = htons((u_short)SMTP_PORT); 29 | inet_pton(AF_INET, "127.0.0.1", &(serverAddr.sin_addr)); 30 | 31 | if (::connect(*sock, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) { 32 | return false; 33 | } 34 | return true; 35 | } 36 | 37 | bool sendMail(const char *from, const char *to, const char *subject, const char *body) 38 | { 39 | SOCKET sock; 40 | if (!connectSMTP(&sock)) { 41 | SLog(L"! smtp mail port connect fail, mail :[%S] body => %S", subject, body); 42 | return false; 43 | } 44 | 45 | smtpWriteLine(sock, "HELO %s", from); 46 | smtpWriteLine(sock, "MAIL FROM: %s", from); 47 | smtpWriteLine(sock, "RCPT TO: %s", to); 48 | smtpWriteLine(sock, "DATA", NULL); 49 | 50 | smtpWriteLine(sock, "From: %s", from); 51 | smtpWriteLine(sock, "To: %s", to); 52 | smtpWriteLine(sock, "Subject: %s", subject); 53 | 54 | smtpWriteLine(sock, "\n", NULL); 55 | 56 | smtpWriteLine(sock, "%s", body); 57 | 58 | smtpWriteLine(sock, ".", NULL); 59 | smtpWriteLine(sock, "QUIT", NULL); 60 | 61 | closesocket(sock); 62 | SLog(L"* send mail [%S]", subject); 63 | 64 | return true; 65 | } -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/SMTPMail.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | bool connectSMTP(SOCKET *sock); 5 | bool sendMail(const char *from, const char *to, const char *subject, const char *body); -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Singleton.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | template 5 | class Singleton 6 | { 7 | protected: 8 | Singleton() {} 9 | ~Singleton() {} 10 | 11 | public: 12 | Singleton(const Singleton&); 13 | Singleton& operator = (const Singleton &); 14 | 15 | static T& getInstance() 16 | { 17 | static T instance; 18 | return instance; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Table.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/Table.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Task.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Task.h" 3 | 4 | TaskNode::TaskNode(Work *workObject, int freqSec, int durationSec) 5 | { 6 | workObject_ = workObject; 7 | freqSec_ = freqSec; 8 | durationSec_ = durationSec; 9 | this->nextTick(); 10 | } 11 | 12 | TaskNode::~TaskNode() 13 | { 14 | SAFE_DELETE(workObject_); 15 | } 16 | 17 | void TaskNode::nextTick() 18 | { 19 | nextTick_ = NOW_TICK() + (tick_t)freqSec_; 20 | } 21 | 22 | bool TaskNode::expired() 23 | { 24 | if (workObject_ == nullptr) { 25 | return true; 26 | } 27 | if (durationSec_ != TICK_INFINTY) { 28 | if (durationSec_ < NOW_TICK()) { 29 | return true; 30 | } 31 | } 32 | return false; 33 | } 34 | 35 | void TaskNode::tick() 36 | { 37 | if (nextTick_ < NOW_TICK()) { 38 | workObject_->tick(); 39 | this->nextTick(); 40 | } 41 | } 42 | 43 | //---------------------------------------------------------------------// 44 | Task::Task(int id) 45 | { 46 | id_ = id; 47 | } 48 | 49 | Task::~Task() 50 | { 51 | for (auto node : taskList_) { 52 | SAFE_DELETE(node); 53 | } 54 | } 55 | 56 | void Task::add(TaskNode *taskNode) 57 | { 58 | taskList_.push_back(taskNode); 59 | } 60 | 61 | void Task::remove(TaskNode *taskNode) 62 | { 63 | taskList_.remove(taskNode); 64 | } 65 | 66 | void Task::process() 67 | { 68 | while (!_shutdown) { 69 | std::vector deleteNodes; 70 | for (auto taskNode : taskList_) { 71 | if (taskNode->expired()) { 72 | deleteNodes.push_back(taskNode); 73 | continue; 74 | } 75 | taskNode->tick(); 76 | } 77 | 78 | for (auto node : deleteNodes) { 79 | this->remove(node); 80 | } 81 | CONTEXT_SWITCH; 82 | } 83 | } 84 | 85 | void Task::run() 86 | { 87 | thread_ = MAKE_THREAD(Task, process); 88 | } 89 | 90 | //---------------------------------------------------------------------// 91 | TaskManager::TaskManager() 92 | { 93 | xml_t config; 94 | if (!loadConfig(&config)) { 95 | return; 96 | } 97 | this->initialize(&config); 98 | } 99 | 100 | void TaskManager::initialize(xml_t *config) 101 | { 102 | xmlNode_t *root = config->FirstChildElement("App")->FirstChildElement("Task"); 103 | if (!root) { 104 | SLog(L"@ not exist task setting"); 105 | return; 106 | } 107 | xmlNode_t *elem = root->FirstChildElement("ThreadCount"); 108 | sscanf_s(elem->GetText(), "%d", &threadCount_); 109 | 110 | for (int i = 0; i < threadCount_; ++i) { 111 | Task *task = new Task(i); 112 | taskPool_.push_back(task); 113 | task->run(); 114 | } 115 | SLog(L"* task thread, [%d] maked", threadCount_); 116 | } 117 | 118 | TaskManager::~TaskManager() 119 | { 120 | for (auto task : taskPool_) { 121 | SAFE_DELETE(task); 122 | } 123 | } 124 | 125 | void TaskManager::add(Work *workObject, int freqSec, int durationSec) 126 | { 127 | const int MINIMAL_THREAD_COUNT = 1; 128 | if (threadCount_ < MINIMAL_THREAD_COUNT) { 129 | return; 130 | } 131 | static int nodeCount = 0; 132 | 133 | TaskNode *node = new TaskNode(workObject, freqSec, durationSec); 134 | int index = nodeCount % threadCount_; 135 | Task *task = taskPool_[index]; 136 | task->add(node); 137 | 138 | ++nodeCount; 139 | } 140 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Task.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "stdafx.h" 3 | 4 | #define TICK_INFINTY 0 5 | 6 | class Work; 7 | class TaskNode 8 | { 9 | Work *workObject_; 10 | int freqSec_; 11 | int durationSec_; 12 | 13 | tick_t nextTick_; 14 | public: 15 | TaskNode(Work *workObject, int freqSec, int durationSec); 16 | ~TaskNode(); 17 | 18 | void nextTick(); 19 | bool expired(); 20 | 21 | void tick(); 22 | }; 23 | 24 | //---------------------------------------------------------------------// 25 | class Task 26 | { 27 | std::list taskList_; 28 | Thread *thread_; 29 | int id_; 30 | 31 | public: 32 | Task(int id); 33 | ~Task(); 34 | void add(TaskNode *taskNode); 35 | void remove(TaskNode *taskNode); 36 | 37 | void process(); 38 | void run(); 39 | }; 40 | 41 | //---------------------------------------------------------------------// 42 | class TaskManager : public Singleton 43 | { 44 | int threadCount_; 45 | std::vector taskPool_; 46 | 47 | public: 48 | TaskManager(); 49 | virtual ~TaskManager(); 50 | 51 | void initialize(xml_t *config); 52 | 53 | void add(Work *workObject, int freqSec, int durationSec); 54 | }; -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Thread.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Thread.h" 3 | #include "Lock.h" 4 | 5 | Thread::Thread(thread_t *thread, wstr_t name) 6 | { 7 | name_ = name; 8 | thread_ = thread; 9 | id_ = thread_->get_id(); 10 | 11 | ThreadManager::getInstance().put(this); 12 | } 13 | 14 | Thread::~Thread() 15 | { 16 | thread_->join(); 17 | SAFE_DELETE(thread_); 18 | SAFE_DELETE(lock_); 19 | } 20 | 21 | threadId_t Thread::id() 22 | { 23 | return id_; 24 | } 25 | 26 | wstr_t &Thread::name() 27 | { 28 | return name_; 29 | } 30 | 31 | void Thread::setLock(Lock *lock) 32 | { 33 | lock_ = lock; 34 | } 35 | 36 | Lock* Thread::lock() 37 | { 38 | return lock_; 39 | } 40 | 41 | //--------------------------------------------------// 42 | ThreadManager::~ThreadManager() 43 | { 44 | for (auto thread : threadPool_){ 45 | SAFE_DELETE(thread.second); 46 | } 47 | } 48 | 49 | void ThreadManager::put(Thread *thread) 50 | { 51 | std::pair node(thread->id(), thread); 52 | threadPool_.insert(node); 53 | SLog(L"* create thread : id[0x%X] name[%s], pool size[%d]", thread->id(), thread->name().c_str(), threadPool_.size()); 54 | } 55 | 56 | void ThreadManager::remove(threadId_t id) 57 | { 58 | auto iter = threadPool_.find(id); 59 | if (iter == threadPool_.end()) { 60 | return; 61 | } 62 | auto thread = iter->second; 63 | threadPool_.erase(iter); 64 | } 65 | 66 | Thread* ThreadManager::at(threadId_t id) 67 | { 68 | if (threadPool_.empty()) { 69 | return nullptr; 70 | } 71 | auto iter = threadPool_.find(id); 72 | if (iter == threadPool_.end()) { 73 | return nullptr; 74 | } 75 | auto thread = iter->second; 76 | return thread; 77 | } 78 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Thread.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/Thread.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/ThreadJobQueue.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/ThreadJobQueue.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Type.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/Type.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/Util.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/ServerCore/ServerLibrary/Util/Util.h -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/tinyXml/tinystr.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | www.sourceforge.net/projects/tinyxml 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any 6 | damages arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any 9 | purpose, including commercial applications, and to alter it and 10 | redistribute it freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must 13 | not claim that you wrote the original software. If you use this 14 | software in a product, an acknowledgment in the product documentation 15 | would be appreciated but is not required. 16 | 17 | 2. Altered source versions must be plainly marked as such, and 18 | must not be misrepresented as being the original software. 19 | 20 | 3. This notice may not be removed or altered from any source 21 | distribution. 22 | */ 23 | #include "stdafx.h" 24 | 25 | #ifndef TIXML_USE_STL 26 | 27 | #include "tinystr.h" 28 | 29 | // Error value for find primitive 30 | const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1); 31 | 32 | 33 | // Null rep. 34 | TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } }; 35 | 36 | 37 | void TiXmlString::reserve (size_type cap) 38 | { 39 | if (cap > capacity()) 40 | { 41 | TiXmlString tmp; 42 | tmp.init(length(), cap); 43 | memcpy(tmp.start(), data(), length()); 44 | swap(tmp); 45 | } 46 | } 47 | 48 | 49 | TiXmlString& TiXmlString::assign(const char* str, size_type len) 50 | { 51 | size_type cap = capacity(); 52 | if (len > cap || cap > 3*(len + 8)) 53 | { 54 | TiXmlString tmp; 55 | tmp.init(len); 56 | memcpy(tmp.start(), str, len); 57 | swap(tmp); 58 | } 59 | else 60 | { 61 | memmove(start(), str, len); 62 | set_size(len); 63 | } 64 | return *this; 65 | } 66 | 67 | 68 | TiXmlString& TiXmlString::append(const char* str, size_type len) 69 | { 70 | size_type newsize = length() + len; 71 | if (newsize > capacity()) 72 | { 73 | reserve (newsize + capacity()); 74 | } 75 | memmove(finish(), str, len); 76 | set_size(newsize); 77 | return *this; 78 | } 79 | 80 | 81 | TiXmlString operator + (const TiXmlString & a, const TiXmlString & b) 82 | { 83 | TiXmlString tmp; 84 | tmp.reserve(a.length() + b.length()); 85 | tmp += a; 86 | tmp += b; 87 | return tmp; 88 | } 89 | 90 | TiXmlString operator + (const TiXmlString & a, const char* b) 91 | { 92 | TiXmlString tmp; 93 | TiXmlString::size_type b_len = static_cast( strlen(b) ); 94 | tmp.reserve(a.length() + b_len); 95 | tmp += a; 96 | tmp.append(b, b_len); 97 | return tmp; 98 | } 99 | 100 | TiXmlString operator + (const char* a, const TiXmlString & b) 101 | { 102 | TiXmlString tmp; 103 | TiXmlString::size_type a_len = static_cast( strlen(a) ); 104 | tmp.reserve(a_len + b.length()); 105 | tmp.append(a, a_len); 106 | tmp += b; 107 | return tmp; 108 | } 109 | 110 | 111 | #endif // TIXML_USE_STL 112 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/Util/tinyXml/tinyxmlerror.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | www.sourceforge.net/projects/tinyxml 3 | Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any 7 | damages arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any 10 | purpose, including commercial applications, and to alter it and 11 | redistribute it freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must 14 | not claim that you wrote the original software. If you use this 15 | software in a product, an acknowledgment in the product documentation 16 | would be appreciated but is not required. 17 | 18 | 2. Altered source versions must be plainly marked as such, and 19 | must not be misrepresented as being the original software. 20 | 21 | 3. This notice may not be removed or altered from any source 22 | distribution. 23 | */ 24 | #include "stdafx.h" 25 | #include "tinyxml.h" 26 | 27 | // The goal of the seperate error file is to make the first 28 | // step towards localization. tinyxml (currently) only supports 29 | // english error messages, but the could now be translated. 30 | // 31 | // It also cleans up the code a bit. 32 | // 33 | 34 | const char* TiXmlBase::errorString[ TiXmlBase::TIXML_ERROR_STRING_COUNT ] = 35 | { 36 | "No error", 37 | "Error", 38 | "Failed to open file", 39 | "Error parsing Element.", 40 | "Failed to read Element name", 41 | "Error reading Element value.", 42 | "Error reading Attributes.", 43 | "Error: empty tag.", 44 | "Error reading end tag.", 45 | "Error parsing Unknown.", 46 | "Error parsing Comment.", 47 | "Error parsing Declaration.", 48 | "Error document empty.", 49 | "Error null (0) or unexpected EOF found in input stream.", 50 | "Error parsing CDATA.", 51 | "Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.", 52 | }; 53 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // ServerLibrary.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | 12 | #include "ServerLibrary.h" -------------------------------------------------------------------------------- /ServerCore/ServerLibrary/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /packetMaker/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /packetMaker/ExcelParser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using System.Data; 8 | using System.Data.OleDb; 9 | 10 | namespace packetMaker 11 | { 12 | class ExcelParser 13 | { 14 | private DataTable excelTable_ = null; 15 | 16 | public ExcelParser(string filePath, string sheetName) 17 | { 18 | this.read(filePath, sheetName); 19 | } 20 | private void read(string filePath, string sheetName) 21 | { 22 | string provider = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + filePath + ";Extended Properties=Excel 12.0"; 23 | 24 | OleDbConnection excel = new OleDbConnection(provider); 25 | excel.Open(); 26 | 27 | string strQuery = "SELECT * FROM [" + sheetName + "$]"; 28 | 29 | OleDbCommand dbCommand = new OleDbCommand(strQuery, excel); 30 | OleDbDataAdapter dataAdapter = new OleDbDataAdapter(dbCommand); 31 | 32 | DataTable table = new DataTable(); 33 | dataAdapter.Fill(table); 34 | 35 | excelTable_ = table; 36 | 37 | dataAdapter.Dispose(); 38 | dbCommand.Dispose(); 39 | 40 | excel.Close(); 41 | excel.Dispose(); 42 | } 43 | ~ExcelParser() 44 | { 45 | excelTable_.Dispose(); 46 | } 47 | 48 | public DataTable table() 49 | { 50 | return excelTable_; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /packetMaker/FactoryMakePacket.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Data; 7 | 8 | namespace packetMaker 9 | { 10 | class FactoryMakePacket : MakePacket 11 | { 12 | private string header_; 13 | private string macro_; 14 | private string tailer_; 15 | 16 | public FactoryMakePacket(string filePath, string formSheet) 17 | : base(filePath, formSheet) 18 | { 19 | } 20 | 21 | protected override void initialize(DataTable excelData) 22 | { 23 | foreach (DataRow row in excelData.Rows) 24 | { 25 | const int titleIdx = 0; 26 | const int parseIdx = 1; 27 | string parseToken = row[titleIdx].ToString(); 28 | if (parseToken.CompareTo("header") == 0) 29 | header_ = row[parseIdx].ToString(); 30 | else if (parseToken.CompareTo("macro") == 0) 31 | macro_ = row[parseIdx].ToString(); 32 | else if (parseToken.CompareTo("tailer") == 0) 33 | tailer_ = row[parseIdx].ToString(); 34 | } 35 | } 36 | 37 | protected override string parse() 38 | { 39 | string parseStr = header_ + nextLine_; 40 | 41 | foreach (DataRow classRow in excelData_.Rows) 42 | { 43 | string nameToken = classRow[0].ToString(); 44 | if (nameToken.StartsWith("#")) 45 | { 46 | continue; 47 | } 48 | const int classNameCol = 0; 49 | 50 | parseStr += string.Format(macro_, classRow[classNameCol].ToString()); 51 | parseStr += nextLine_; 52 | } 53 | parseStr += tailer_; 54 | return parseStr; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /packetMaker/HeaderMakePacket.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using System.Data; 8 | 9 | namespace packetMaker 10 | { 11 | class HeaderMakePacket : MakePacket 12 | { 13 | private string header_; 14 | private string enum_; 15 | private string tailer_; 16 | private int packetIndextStart_ = 128; 17 | private string packetMakeDate = "2015/03/14 13:14:41"; 18 | 19 | public HeaderMakePacket(string filePath, string formSheet) 20 | : base(filePath, formSheet) 21 | { 22 | } 23 | 24 | protected override void initialize(DataTable excelData) 25 | { 26 | foreach (DataRow row in excelData.Rows) 27 | { 28 | const int titleIdx = 0; 29 | const int parseIdx = 1; 30 | string parseToken = row[titleIdx].ToString(); 31 | if (parseToken.CompareTo("header") == 0) 32 | header_ = row[parseIdx].ToString(); 33 | else if (parseToken.CompareTo("enum") == 0) 34 | enum_ = row[parseIdx].ToString(); 35 | else if (parseToken.CompareTo("tailer") == 0) 36 | tailer_ = row[parseIdx].ToString(); 37 | } 38 | } 39 | 40 | protected override string parse() 41 | { 42 | string parseStr = string.Format(header_, packetMakeDate) + nextLine_; 43 | 44 | int index = packetIndextStart_; 45 | foreach (DataRow classRow in excelData_.Rows) 46 | { 47 | string nameToken = classRow[0].ToString(); 48 | if (nameToken.StartsWith("#")) 49 | { 50 | continue; 51 | } 52 | const int classNameCol = 0; 53 | 54 | parseStr += string.Format(enum_, index++, classRow[classNameCol].ToString()); 55 | parseStr += nextLine_; 56 | } 57 | parseStr += tailer_; 58 | 59 | return parseStr; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /packetMaker/MakePacket.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using System.Data; 8 | using System.Data.OleDb; 9 | using System.IO; 10 | 11 | namespace packetMaker 12 | { 13 | class MakePacket 14 | { 15 | public string nextLine_ = "#newLine"; 16 | public string tab_ = " "; 17 | public string scopeIn_ = "`"; //임시 중괄호 18 | public string scopeOut_ = "~"; //임시 중괄호 19 | 20 | protected string excelFilePath_; 21 | protected DataTable excelData_; 22 | public MakePacket(string filePath, string formSheet) 23 | { 24 | ExcelParser excel = new ExcelParser(filePath, formSheet); 25 | this.initialize(excel.table()); 26 | 27 | excelFilePath_ = filePath; 28 | } 29 | 30 | public void make(string dataSheet, string outFIleName) 31 | { 32 | ExcelParser excel_ = new ExcelParser(excelFilePath_, dataSheet); 33 | excelData_ = excel_.table(); 34 | this.writeFile(this.parse(), outFIleName); 35 | } 36 | 37 | protected virtual void initialize(DataTable excelData) 38 | { 39 | } 40 | 41 | protected virtual string parse() 42 | { 43 | return null; 44 | } 45 | 46 | private void writeFile(string parseStr, string outFIleName) 47 | { 48 | //중괄호는 C언어로 보면 %d, %s 같은 개념이라 파싱할때 못썻으니 49 | //파일로 쓰기 전에에 임시 중괄호를 진짜 중괄호로 바꾼다. 50 | parseStr = parseStr.Replace(scopeIn_, "{"); 51 | parseStr = parseStr.Replace(scopeOut_, "}"); 52 | 53 | FileStream fs; 54 | fs = new FileStream(outFIleName, FileMode.Create); 55 | StreamWriter write = new StreamWriter(fs); 56 | string[] lines = System.Text.RegularExpressions.Regex.Split(parseStr, nextLine_); 57 | foreach (string line in lines) 58 | { 59 | write.WriteLine(line); 60 | Console.WriteLine(line); 61 | } 62 | write.Close(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /packetMaker/MakePacketStruct.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using System.Data; 8 | 9 | namespace packetMaker 10 | { 11 | class MakePacketStruct : MakePacket 12 | { 13 | private string header_; //file header macro 14 | private string classHeader_; //class macro 15 | private string packetType_; //.. 16 | private string encode_; 17 | private string streamIn_; 18 | private string stringIn_; 19 | private string decode_; 20 | private string streamOut_; 21 | private string stringOut_; 22 | 23 | public MakePacketStruct(string filePatch, string formSheet) 24 | : base(filePatch, formSheet) 25 | { 26 | } 27 | 28 | public override void initialize(DataTable excelData) 29 | { 30 | foreach (DataRow row in excelData.Rows) 31 | { 32 | const int titleIdx = 0; 33 | const int parseIdx = 1; 34 | string parseToken = row[titleIdx].ToString(); 35 | if (parseToken.CompareTo("header") == 0) 36 | header_ = row[parseIdx].ToString(); 37 | else if (parseToken.CompareTo("classHeader") == 0) 38 | classHeader_ = row[parseIdx].ToString(); 39 | else if (parseToken.CompareTo("packetType") == 0) 40 | packetType_ = row[parseIdx].ToString(); 41 | else if (parseToken.CompareTo("encode") == 0) 42 | encode_ = row[parseIdx].ToString(); 43 | else if (parseToken.CompareTo("streamIn") == 0) 44 | streamIn_ = row[parseIdx].ToString(); 45 | else if (parseToken.CompareTo("stringIn") == 0) 46 | stringIn_ = row[parseIdx].ToString(); 47 | else if (parseToken.CompareTo("decode") == 0) 48 | decode_ = row[parseIdx].ToString(); 49 | else if (parseToken.CompareTo("streamOut") == 0) 50 | streamOut_ = row[parseIdx].ToString(); 51 | else if (parseToken.CompareTo("stringOut") == 0) 52 | stringOut_ = row[parseIdx].ToString(); 53 | } 54 | } 55 | 56 | private string parseMemberVal(DataRow classRow) 57 | { 58 | string parseStr = ""; 59 | 60 | int columnIdx = 2; 61 | foreach (DataColumn Col in excelData_.Columns) 62 | { 63 | if (columnIdx++ == 2) 64 | { 65 | continue; 66 | } 67 | string token = classRow[Col].ToString(); 68 | if (token == "") 69 | { 70 | break; 71 | } 72 | parseStr += tab_ + token; 73 | if ((columnIdx % 2) == 0) 74 | { 75 | parseStr += " "; 76 | } 77 | else 78 | { 79 | parseStr += ";" + nextLine_; 80 | } 81 | } 82 | return parseStr; 83 | } 84 | 85 | private string parseFunction(DataRow classRow, string streamStr, string stringStr) 86 | { 87 | string parseStr = ""; 88 | int columnIdx = 2; 89 | string typeToken = ""; 90 | foreach (DataColumn Col in excelData_.Columns) 91 | { 92 | if ((columnIdx++ % 2) != 0 || columnIdx == 3) 93 | { 94 | typeToken = classRow[Col].ToString(); 95 | continue; 96 | } 97 | string valToken = classRow[Col].ToString(); 98 | if (valToken == "") 99 | { 100 | break; 101 | } 102 | 103 | parseStr += string.Format(streamStr, valToken); 104 | parseStr += nextLine_; 105 | } 106 | return parseStr; 107 | } 108 | 109 | private string parseEncode(DataRow classRow) 110 | { 111 | string parseStr = nextLine_; 112 | parseStr += encode_ + scopeIn_ + nextLine_; 113 | parseStr += parseFunction(classRow, streamIn_, stringIn_); 114 | parseStr += tab_ + scopeOut_ + nextLine_; 115 | return parseStr; 116 | } 117 | 118 | private string parseDecode(DataRow classRow) 119 | { 120 | string parseStr = nextLine_; 121 | parseStr += decode_ + scopeIn_ + nextLine_; 122 | parseStr += parseFunction(classRow, streamOut_, stringOut_); 123 | parseStr += tab_ + scopeOut_ + nextLine_; 124 | return parseStr; 125 | } 126 | 127 | public override string parse() 128 | { 129 | string classStatrMacro = classHeader_ + nextLine_ 130 | + scopeIn_ + nextLine_ 131 | + packetType_ + nextLine_; 132 | string classEndMacro = scopeOut_ + ";" + nextLine_ + nextLine_; 133 | 134 | string parseStr = header_ + nextLine_ + nextLine_; 135 | foreach (DataRow classRow in excelData_.Rows) 136 | { 137 | const int classNameCol = 0; 138 | const int valTokenCol = 1; 139 | 140 | parseStr += string.Format(classStatrMacro, classRow[classNameCol].ToString()); 141 | string token = classRow[valTokenCol].ToString(); 142 | if (token == "") 143 | { 144 | parseStr += classEndMacro; 145 | continue; 146 | } 147 | parseStr += parseMemberVal(classRow); 148 | parseStr += parseEncode(classRow); 149 | parseStr += parseDecode(classRow); 150 | parseStr += classEndMacro; 151 | } 152 | return parseStr; 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /packetMaker/ParseExcel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using System.Data; 8 | using System.Data.OleDb; 9 | 10 | namespace packetMaker 11 | { 12 | class ParseExcel 13 | { 14 | private DataTable excelTable_ = null; 15 | 16 | public ParseExcel(string filePatch, string sheetName) 17 | { 18 | this.read(filePatch, sheetName); 19 | } 20 | private void read(string filePatch, string sheetName) 21 | { 22 | string provider = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + filePatch + ";Extended Properties=Excel 12.0"; 23 | 24 | OleDbConnection excel = new OleDbConnection(provider); 25 | excel.Open(); 26 | 27 | string strQuery = "SELECT * FROM [" + sheetName + "$]"; 28 | 29 | OleDbCommand dbCommand = new OleDbCommand(strQuery, excel); 30 | OleDbDataAdapter dataAdapter = new OleDbDataAdapter(dbCommand); 31 | 32 | DataTable table = new DataTable(); 33 | dataAdapter.Fill(table); 34 | 35 | excelTable_ = table; 36 | 37 | dataAdapter.Dispose(); 38 | dbCommand.Dispose(); 39 | 40 | excel.Close(); 41 | excel.Dispose(); 42 | } 43 | ~ParseExcel() 44 | { 45 | excelTable_.Dispose(); 46 | } 47 | 48 | public DataTable table() 49 | { 50 | return excelTable_; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /packetMaker/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 어셈블리의 일반 정보는 다음 특성 집합을 통해 제어됩니다. 6 | // 어셈블리와 관련된 정보를 수정하려면 7 | // 이 특성 값을 변경하십시오. 8 | [assembly: AssemblyTitle("packetMaker")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("packetMaker")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에 18 | // 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면 19 | // 해당 형식에 대해 ComVisible 특성을 true로 설정하십시오. 20 | [assembly: ComVisible(false)] 21 | 22 | // 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다. 23 | [assembly: Guid("c11a7960-aae5-4408-89b4-7e8c52becc75")] 24 | 25 | // 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다. 26 | // 27 | // 주 버전 28 | // 부 버전 29 | // 빌드 번호 30 | // 수정 버전 31 | // 32 | // 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 버전이 자동으로 33 | // 지정되도록 할 수 있습니다. 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /packetMaker/bin/Debug/Packet.h: -------------------------------------------------------------------------------- 1 | #include "packetHeader.h" 2 | #include "Stream.h" 3 | 4 | struct Packet { 5 | void encode(Stream &stream) {} 6 | void decode(Stream &stream) {} 7 | }; 8 | 9 | struct PK_C_REQ_ID_PW : Packet 10 | { 11 | int packetType() { return E_C_REQ_ID_PW; } 12 | string id; 13 | string password; 14 | 15 | void encode(Stream &stream) { 16 | stream.putString(id); 17 | stream.putString(password); 18 | } 19 | 20 | void decode(Stream &stream) { 21 | stream.getString(&id); 22 | stream.getString(&password); 23 | } 24 | }; 25 | 26 | struct PK_S_REQ_ID_ID_PW : Packet 27 | { 28 | int packetType() { return E_S_REQ_ID_ID_PW; } 29 | bool result; 30 | 31 | void encode(Stream &stream) { 32 | stream << result; 33 | } 34 | 35 | void decode(Stream &stream) { 36 | stream >> &result; 37 | } 38 | }; 39 | 40 | struct PK_C_NOTIFY_HEARTBEET : Packet 41 | { 42 | int packetType() { return E_C_NOTIFY_HEARTBEET; } 43 | }; 44 | 45 | struct PK_C_REQ_CHATTING : Packet 46 | { 47 | int packetType() { return E_C_REQ_CHATTING; } 48 | string text; 49 | 50 | void encode(Stream &stream) { 51 | stream.putString(text); 52 | } 53 | 54 | void decode(Stream &stream) { 55 | stream.getString(&text); 56 | } 57 | }; 58 | 59 | struct PK_S_REQ_CHATTING : Packet 60 | { 61 | int packetType() { return E_S_REQ_CHATTING; } 62 | string id; 63 | string text; 64 | 65 | void encode(Stream &stream) { 66 | stream.putString(id); 67 | stream.putString(text); 68 | } 69 | 70 | void decode(Stream &stream) { 71 | stream.getString(&id); 72 | stream.getString(&text); 73 | } 74 | }; 75 | 76 | 77 | -------------------------------------------------------------------------------- /packetMaker/bin/Debug/PacketHeader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../stdafx.h" 3 | 4 | enum EPacket { 5 | /*0*/ E_C_REQ_ID_PW, 6 | /*1*/ E_S_REQ_ID_ID_PW, 7 | /*2*/ E_C_NOTIFY_HEARTBEET, 8 | /*3*/ E_C_REQ_CHATTING, 9 | /*4*/ E_S_REQ_CHATTING, 10 | }; 11 | -------------------------------------------------------------------------------- /packetMaker/bin/Debug/packetMaker.vshost.exe.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packetMaker/bin/Debug/packetMaker.vshost.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /packetMaker/main.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Runtime.InteropServices; 7 | 8 | namespace packetMaker 9 | { 10 | class main 11 | { 12 | //프로젝트 놓은 디렉토리 설정 13 | static string patch_ = "D:\\Work\\2014년\\roseserver\\trunk"; 14 | static string serverProjectName_ = "\\ServerCore\\ServerLibrary"; 15 | static string serverProjectPath_ = patch_ + serverProjectName_ + "\\Net\\Packet"; 16 | 17 | static string clientProjectName_ = "\\DummyClient"; 18 | static string clientProjectPath_ = patch_ + clientProjectName_ + "\\DummyClient\\Source\\PacketGen"; 19 | 20 | static string excelPath_ = patch_ + "\\packetMaker\\packetData.xlsx"; 21 | static string dataSheet_ = "packetData"; 22 | static void Main(string[] args) 23 | { 24 | Console.WriteLine("* packet maker run!!! "); 25 | ClassMakePacket serverClass = new ClassMakePacket(excelPath_, "PacketClass"); 26 | serverClass.make(dataSheet_, serverProjectPath_ + "\\PacketClass.h"); 27 | 28 | HeaderMakePacket serverHeader = new HeaderMakePacket(excelPath_, "PacketHeader"); 29 | serverHeader.make(dataSheet_, serverProjectPath_ + "\\PacketHeader.h"); 30 | 31 | FactoryMakePacket serverFactory = new FactoryMakePacket(excelPath_, "PacketFactory"); 32 | serverFactory.make(dataSheet_, serverProjectPath_ + "\\PacketFactory.h"); 33 | 34 | HeaderMakePacket clientHeader = new HeaderMakePacket(excelPath_, "clientPacketHeader"); 35 | clientHeader.make(dataSheet_, clientProjectPath_ + "\\PacketHeader.cs"); 36 | 37 | ClientClassMakePacket clientClass = new ClientClassMakePacket(excelPath_, "clientPacketClass"); 38 | clientClass.make(dataSheet_, clientProjectPath_ + "\\PacketClass.cs"); 39 | 40 | FactoryMakePacket clientFactory = new FactoryMakePacket(excelPath_, "clientPacketFactory"); 41 | clientFactory.make(dataSheet_, clientProjectPath_ + "\\PacketFactory.cs"); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packetMaker/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/packetMaker/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs -------------------------------------------------------------------------------- /packetMaker/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/packetMaker/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs -------------------------------------------------------------------------------- /packetMaker/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/packetMaker/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs -------------------------------------------------------------------------------- /packetMaker/packetData.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/packetMaker/packetData.xlsx -------------------------------------------------------------------------------- /packetMaker/packetMaker.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {27B177C3-CE22-49E1-9CAD-42C7154300A3} 8 | Exe 9 | Properties 10 | packetMaker 11 | packetMaker 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | false 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 71 | -------------------------------------------------------------------------------- /게임 기본 쿼리.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galaxywiz/RoseServer/7ce93937f6f896728839816986223180aeaac4d9/게임 기본 쿼리.sql --------------------------------------------------------------------------------