V-IntSockBase.asm
资源名称:VeMU.rar [点击查看]
上传用户:santakups8
上传日期:2021-03-23
资源大小:544k
文件大小:13k
源码类别:
模拟服务器
开发平台:
Asm
- ;EasyCodeName=Module1,1
- ;-----------------------------------------------------------------------------------
- ; VeMU
- ; Its a package that allows the user to set his own server of the game
- ; "MuOnline", this is not an emulator since i am not "emulating"
- ; what the actual games does, i am "creating" a method for set a Server
- ; of this Game.
- ;
- ; Copyright (C) 2010 FelipeYa馿z
- ;
- ; This program is free software: you can redistribute it and/or modify
- ; it under the terms of the GNU General Public License as published by
- ; the Free Software Foundation, either version 3 of the License, or
- ; (at your option) any later version.
- ;
- ; This program is distributed in the hope that it will be useful,
- ; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ; GNU General Public License for more details.
- ;
- ; You should have received a copy of the GNU General Public License
- ; along with this program. If not, see http://www.gnu.org/licenses/.
- ;-----------------------------------------------------------------------------------
- ;-----------------------------------------------------------------------------------
- ; -----------------
- ; Coded /
- ; By /
- ; -={FeN$x)=-
- ; / Felipe Y.
- ; /
- ; -----------------
- ; Programming Lang: ASM
- ; Country: Chile
- ; My respect for all those who lost their lifes
- ; In the earthquake of my country...
- ; Let god take their spirits home...
- ;-----------------------------------------------------------------------------------
- ;///////////////////////////////////////////////////////////////////////////////////////////////////
- ; Fully ended, internal system connection of Valkyre emulator
- ; This is an approach to editable and fexible code, but at the same time very compressed,
- ; its a good emulation of WZ internal system connection. its not 100%, like original one,
- ; but its more compressed, avoiding some stupid WZ things and other things that C++ compiler do.
- ;
- ; This struct and procedures are used for internal connections to other clients like
- ; JoynServer, ConnectServer, RankingServer, DataServers & ExDB
- ; Coded by [INDIGO]FeN$x
- ;////////////////////////////////////////////////////////////////////////////////////////////////////
- V_Sock_CreateSocket Proto :Dword
- V_Sock_MakeAddr Proto :Dword, :Dword
- .Const
- .Data?
- .Data
- .Code
- V_Sock_SetAll Proc uses ecx
- Local pWSADATA:WSADATA ;Point to local struct
- assume ecx:ptr InternalClients_Struct
- Invoke WSAStartup, 202H, Addr pWSADATA
- .If (Eax != 0)
- RGB 255, 127, 80 ;Coral (orange ligth)
- invoke vprint, $CTA0("SockInteral:] Error on while loading WSA"), eax
- xor eax, eax
- .else
- mov edx, Dword ptr pWSADATA
- and edx, 0FFFFh ;Word
- .if (edx == 2) ;Check version high byte
- mov edx, Dword ptr pWSADATA
- and edx, 0FFFFh ;Word
- shr edx, 8
- and edx, 0FFh ;Byte
- .if (edx == 2) ;Check version low byte
- push ecx ;Save struct
- invoke V_Sock_CreateSocket, [ecx].TCPorUDP ;Create a socket
- .if (eax == NULL)
- RGB 255, 64, 64 ;Coral (orange ligth)
- invoke vprint, $CTA0("SockInteral:] Error while creating Socket"), eax
- xor eax, eax
- .else
- invoke V_Sock_MakeAddr, [ecx].IPorName, [ecx].Port ;Convert IP or HOST name into internet address
- .if (eax == NULL)
- RGB 255, 64, 64 ;Coral (orange ligth)
- invoke vprint, $CTA0("SockInteral:] Error while resolving Address"), eax
- xor eax, eax
- .else
- call V_Sock_Connect ;Connect
- .if (eax == NULL)
- RGB 255, 64, 64 ;Coral (orange ligth)
- invoke vprint, $CTA0("SockInteral:] Error while trying to connect to port:[%d]"), eax, [ecx].Port
- xor eax, eax
- .endif
- .endif
- .endif
- .else
- RGB 255, 64, 64 ;Coral (orange ligth)
- invoke vprint, $CTA0("SockInteral:] WSA Version its 2.[%d], please use 2.2"), eax, edx
- .endif
- .else
- RGB 255, 64, 64 ;Coral (orange ligth)
- invoke vprint, $CTA0("SockInteral:] WSA Version its too old, please use 2.2"), eax
- .endif
- .endif
- pop ecx ;Return struct
- .if (eax == NULL)
- call V_Sock_Close ;Close if something went wrong
- xor eax, eax
- .endif
- Ret
- V_Sock_SetAll EndP
- V_Sock_Send Proc Uses Ecx pPacket:DWord, PacketLength:DWord
- Local MyStruct:DWord
- Local BytesSend:DWord
- Local ExtraBytes:DWord
- Mov MyStruct, Ecx
- Mov ExtraBytes, 0
- Mov BytesSend, 0
- Assume Ecx:Ptr InternalClients_Struct
- mov eax, pPacket
- mov edx, PacketLength
- mov [ecx].pSendPacket, eax ;Save in case that we cant send the packet, caused WSAEWOULDBLOCK
- mov [ecx].LastLengthPacket, edx ;Save in case that we cant send the packet, caused WSAEWOULDBLOCK
- .If (edx == 0) ;If packet length its 0
- RGB 255, 64, 64
- invoke vprint, $CTA0("SockInteral:] Trying to send a NULL packet"), eax
- Xor Eax, Eax
- .Elseif ([Ecx].Connected == 0) ;If we arent connected
- RGB 255, 64, 64
- invoke vprint, $CTA0("SockInteral:] You arent connected to the internal client for send"), eax
- Xor Eax, Eax
- .Elseif (PacketLength > MAX_BUFF_LENGTH) ;If more than max buffer length
- RGB 255, 64, 64
- invoke vprint, $CTA0("SockInteral:] The packet exceed the MAX_BUFFER_LENGTH constant"), eax
- Xor Eax, Eax
- .Else
- .Repeat
- Mov Eax, PacketLength
- Mov Edx, pPacket
- Add Edx, ExtraBytes ;Packet + ExtraBytes if they are
- Sub Eax, ExtraBytes ;PacketLength - ExtraBytes = NewPacketLength (if there are extra bytes)
- Invoke send, [Ecx].Sock, Edx, Eax, NULL
- Mov Ecx, MyStruct
- Mov BytesSend, Eax
- .If (Eax == -1)
- Invoke WSAGetLastError
- .If (Eax != WSAEWOULDBLOCK) ;If connection is busy
- RGB 255, 64, 64
- invoke vprint, $CTA0("SockInteral:] Connection busy for send, will resend when ready"), eax
- mov eax, 2
- .Else
- mov edx, eax
- RGB 255, 64, 64
- invoke vprint, $CTA0("SockInteral:] Error when sending [%d]"), eax, edx
- Xor Eax, Eax
- .Endif
- .Else
- Mov Eax, PacketLength
- .If (BytesSend != Eax) ;If not all the bytes where sended
- Mov Edx, BytesSend
- Add ExtraBytes, Edx
- .Else
- mov eax, 1
- .Endif
- .Endif
- .Until (ExtraBytes == 0)
- .Endif
- .if (eax == 1) || (eax == 0) ;If all went OK or a error happend
- invoke V_ZeroBuff, Addr InternalPacket, MAX_PACKETSEND_LENGTH ;Clean the packet buffer
- .else ;If WSAEWOULDBLOCK then i dont clean the packet buffer
- .endif
- Assume Ecx:Nothing
- Ret
- V_Sock_Send EndP
- V_Sock_Recv Proc
- Local MyStruct:DWord
- Local BytesRecv:DWord
- Local RecvPacketLength:DWord
- Local RecvPacketHeader:Dword
- Local localExtraBytes:DWord
- .data
- ExtraBytes DD ? ;Extra bytes in global mode
- .code
- Mov localExtraBytes, 0
- mov RecvPacketLength, 0
- Mov MyStruct, Ecx
- Assume Ecx:Ptr InternalClients_Struct
- lea edx, [ecx].RecvBuff
- add edx, ExtraBytes ;If there are extra bytes
- Invoke recv, [Ecx].Sock, edx, [ecx].RecvBuffSize, 0
- Mov BytesRecv, Eax
- .If (Eax == 0)
- RGB 255, 64, 64
- invoke vprint, $CTA0("SockInteral:] Error no bytes recv"), eax
- mov eax, -1
- .ElseIf (Eax == -1)
- Invoke WSAGetLastError
- .If (Eax == WSAEWOULDBLOCK) ;if connection is busy
- RGB 255, 64, 64
- invoke vprint, $CTA0("SockInteral:] Connection busy to recv, we will recv later"), eax
- mov eax, 1 ;We will try later to recv
- .Else
- RGB 255, 64, 64
- invoke vprint, $CTA0("SockInteral:] Internal error while recv"), eax
- mov eax, -1
- .EndIf
- .Else
- Mov Ecx, MyStruct
- .If (BytesRecv > 3) ;if less than 3 bytes
- RGB 255, 64, 64
- invoke vprint, $CTA0("SockInteral:] Error, less than 3 bytes recv"), eax
- mov eax, -1
- .Else
- CheckC1orC2:
- Mov Edx, localExtraBytes
- Movsx eax, Byte Ptr [[Ecx].RecvBuff + Edx]
- .If (Al == 0C1H)
- Xor Eax, Eax
- Mov Edx, localExtraBytes
- Movsx eax, Byte Ptr [[Ecx].RecvBuff + Edx + 1]
- Mov RecvPacketLength, Eax
- Movsx eax, Byte Ptr [[Ecx].RecvBuff + Edx + 2]
- Mov RecvPacketHeader, eax
- .ElseIf (Al == 0C2H)
- Mov Edx, localExtraBytes
- Xor Eax, Eax
- Xor Ebx, Ebx
- Movsx eax, Byte Ptr [[Ecx].RecvBuff + Edx + 1]
- Shl Eax, 8
- Movsx ebx, Byte Ptr [[Ecx].RecvBuff + Edx + 2]
- Or Eax, Ebx
- Mov RecvPacketLength, Eax
- Movsx eax, Byte Ptr [[Ecx].RecvBuff + Edx + 3]
- Mov RecvPacketHeader, eax
- .Else
- RGB 255, 64, 64
- invoke vprint, $CTA0("SockInteral:] Invalid packet header"), eax
- mov ExtraBytes, 0
- mov eax, -1
- jmp EndRecv
- .EndIf
- .If (RecvPacketLength == 0) ;If packet length its 0
- RGB 255, 64, 64
- invoke vprint, $CTA0("SockInteral:] Invalid length of packet"), eax
- mov ExtraBytes, 0
- mov eax, -1
- .Else
- Mov Ecx, MyStruct
- Mov Edx, RecvPacketLength
- .If (Edx <= BytesRecv) ;If the byte of packet is less or equal than the recived bytes
- Xor Ebx, Ebx
- Lea Edx, [Ecx].ProtocolAddr
- Lea Eax, [Ecx].RecvBuff
- Add Eax, localExtraBytes
- Mov ebx, RecvPacketHeader
- Push RecvPacketLength
- Push Eax ;RecvBuffer
- Push Ebx ;PacketHeader
- Call Edx ;call Protocol core depending of the struct used
- Mov Ecx, MyStruct
- Mov Edx, RecvPacketLength
- Add localExtraBytes, Edx
- Sub BytesRecv, Edx
- .If (BytesRecv < 0) ;if still bytes that we havent readed
- Jmp CheckC1orC2
- CheckLoop:
- .Else
- mov ExtraBytes, 0 ;I make sure to set this
- mov eax, 1
- .EndIf
- .Else ;If byte packet of length says there still more bytes that the ones we actual recieve
- mov edx, BytesRecv
- add ExtraBytes, edx ;Save to global counter
- xor eax, eax
- .Endif
- .Endif
- .EndIf
- .EndIf
- EndRecv:
- .if (eax == -1) ;If some error has happen
- mov ecx, MyStruct
- invoke V_ZeroBuff, [ecx].RecvBuff, [ecx].RecvBuffSize ;Clean the buffer
- .elseif (eax == 1) ;If we end succesfull reading the packet
- mov ecx, MyStruct
- invoke V_ZeroBuff, [ecx].RecvBuff, [ecx].RecvBuffSize ;Clean the buffer
- .else ;If we expecting to link the next packet comming to the current we dont clean the buffer
- .endif
- Assume Ecx:Nothing
- Ret
- V_Sock_Recv EndP
- ;/////////////////////////////////////////
- ;Create Socket
- ;////////////////////////////////////////
- V_Sock_CreateSocket Proc Uses Ecx UDPorTCP:Dword
- assume ecx:ptr InternalClients_Struct
- .If (UDPorTCP == 1) ;UDP
- Mov Eax, SOCK_DGRAM
- .Else
- Mov Eax, SOCK_STREAM
- .EndIf
- Lea Ecx, [Ecx].Sock
- Push Ecx
- Invoke socket, AF_INET, Eax, IPPROTO_IP
- Pop Ecx
- .If (Eax == -1)
- mov dword ptr [ecx], eax ;Unvalid Socket
- xor eax, eax
- .Else
- Mov DWord Ptr [Ecx], Eax ;Save socket in struct
- .EndIf
- Assume Ecx:Nothing
- Ret
- V_Sock_CreateSocket EndP
- ;///////////////////////////////////////////////////////
- ;Connect procedure
- ;///////////////////////////////////////////////////////
- V_Sock_Connect Proc uses ecx
- assume ecx:ptr InternalClients_Struct
- push ecx
- Invoke connect, [Ecx].Sock, addr [Ecx].SockAddr, SizeOf sockaddr_in
- pop ecx
- .If (Eax == -1)
- Invoke WSAGetLastError
- .If (Eax != WSAEWOULDBLOCK)
- Xor Eax, Eax
- .else
- push ecx
- Invoke WSAAsyncSelect, [Ecx].Sock, [ecx].hWnd, [ecx].MSGID, FD_READ + FD_CLOSE
- pop ecx
- .If (Eax == -1)
- Xor Eax, Eax
- .Else
- Mov [Ecx].Connected, 1 ;Already connected
- .EndIf
- .endif
- .endif
- Assume Ecx:Nothing
- Ret
- V_Sock_Connect EndP
- ;/////////////////////////////////////////////////////////
- ;Custom proc for make an Host address from input arguments
- ;and save the address in UDP struct
- ;RETURN VALUES: 1 == SUCCESS, 0 == FAILURE
- ;/////////////////////////////////////////////////////////
- V_Sock_MakeAddr Proc Uses Ecx IPorName:DWord, Port:DWord
- Local MyStruct:DWord
- assume ecx:ptr InternalClients_Struct
- lea ecx, [ecx].SockAddr
- Assume Ecx:Ptr sockaddr_in
- Push Ecx
- Invoke ntohs, Port
- Pop Ecx
- Mov [Ecx].sin_family, 2
- Mov [Ecx].sin_port, Ax
- push ecx
- Invoke inet_addr, IPorName ;Take by IP
- pop ecx
- Mov [Ecx].sin_addr, Eax
- mov MyStruct, ecx ;Save for now struct in a variable
- .If (Eax == -1)
- Invoke gethostbyname, IPorName ;Take by Host Name
- .If (Eax == 0)
- .Else
- Assume Eax:Ptr hostent
- Mov Ecx, MyStruct
- Mov Edx, DWord Ptr [Eax].h_list
- Mov Ebx, [Edx] ;EBX = Host name converted
- Invoke MemCopy, Ebx, Addr [Ecx].sin_addr, [Eax].h_len ;Save into sin_addr in our struct
- .EndIf
- .EndIf
- Assume Ecx:Nothing
- assume eax:Nothing
- Ret
- V_Sock_MakeAddr EndP
- ;/////////////////////////////////////////
- ;Close socket
- ;////////////////////////////////////////
- V_Sock_Close Proc Uses Ecx
- Assume Ecx:Ptr InternalClients_Struct
- Push Ecx
- Invoke shutdown, [Ecx].Sock, NULL
- Pop Ecx
- Push Ecx
- Invoke closesocket, [Ecx].Sock
- Pop Ecx
- Mov [Ecx].Sock, -1
- Mov [Ecx].Connected, 0
- Assume Ecx:Nothing
- Ret
- V_Sock_Close EndP