aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/Socket.h
blob: c4ec9fc8ceecccd7cef94393a7961e9602a5f7cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#pragma once
#include <xrnm.h>
#include <queue>
#include <qnet.h>
#include "InputStream.h"
#include "OutputStream.h"

#define SOCKET_CLIENT_END 0
#define SOCKET_SERVER_END 1

class SocketAddress;
class ServerConnection;

class Socket
{
public:
	// 4J Added so we can add a priority write function
	class SocketOutputStream : public OutputStream
	{
	public:
		// The flags are those that can be used for the QNet SendData function
		virtual void writeWithFlags(byteArray b, unsigned int offset, unsigned int length, int flags) { write(b, offset, length); }
	};

private:
	class SocketInputStreamLocal : public InputStream
	{
	public:
		bool m_streamOpen;
	private:
		int	m_queueIdx;
	public:
		SocketInputStreamLocal(int queueIdx);

		virtual int read();
		virtual int read(byteArray b);
		virtual int read(byteArray b, unsigned int offset, unsigned int length);
		virtual void close();
		virtual int64_t skip(int64_t n) { return n; } // 4J Stu - Not implemented
		virtual void flush() {}
	};

	class SocketOutputStreamLocal : public SocketOutputStream
	{
	public:
		bool m_streamOpen;
	private:
		int m_queueIdx;
	public:
		SocketOutputStreamLocal(int queueIdx);

		virtual void write(unsigned int b);
		virtual void write(byteArray b);
		virtual void write(byteArray b, unsigned int offset, unsigned int length);
		virtual void close();
		virtual void flush() {}
	};

	class SocketInputStreamNetwork : public InputStream
	{
		bool m_streamOpen;
		int	m_queueIdx;
		Socket *m_socket;
	public:
		SocketInputStreamNetwork(Socket *socket, int queueIdx);

		virtual int read();
		virtual int read(byteArray b);
		virtual int read(byteArray b, unsigned int offset, unsigned int length);
		virtual void close();
		virtual int64_t skip(int64_t n) { return n; } // 4J Stu - Not implemented
		virtual void flush() {}
	};
	class SocketOutputStreamNetwork : public SocketOutputStream
	{
		bool m_streamOpen;
		int	m_queueIdx;
		Socket *m_socket;
	public:
		SocketOutputStreamNetwork(Socket *socket, int queueIdx);

		virtual void write(unsigned int b);
		virtual void write(byteArray b);
		virtual void write(byteArray b, unsigned int offset, unsigned int length);
		virtual void writeWithFlags(byteArray b, unsigned int offset, unsigned int length, int flags);
		virtual void close();
		virtual void flush() {}
	};

	bool m_hostServerConnection;			// true if this is the connection between the host player and server
	bool m_hostLocal;						// true if this player on the same machine as the host
	int m_end;								// 0 for client side or 1 for host side

	// For local connections between the host player and the server
	static CRITICAL_SECTION s_hostQueueLock[2];
	static std::queue<byte> s_hostQueue[2];
	static SocketOutputStreamLocal *s_hostOutStream[2];
	static SocketInputStreamLocal *s_hostInStream[2];

	// For network connections
	std::queue<byte> m_queueNetwork[2];		// For input data
	CRITICAL_SECTION m_queueLockNetwork[2];  // For input data
	SocketInputStreamNetwork *m_inputStream[2];
	SocketOutputStreamNetwork *m_outputStream[2];
	bool m_endClosed[2];

	// Host only connection class
	static ServerConnection *s_serverConnection;

	BYTE networkPlayerSmallId;
public:
	C4JThread::Event* m_socketClosedEvent;

	INetworkPlayer *getPlayer();
	void setPlayer(INetworkPlayer *player);

public:
	static void Initialise(ServerConnection *serverConnection);
	Socket(bool response = false);								// 4J - Create a local socket, for end 0 or 1 of a connection
	Socket(INetworkPlayer *player, bool response  = false, bool hostLocal = false);		// 4J - Create a socket for an INetworkPlayer
	SocketAddress *getRemoteSocketAddress();
	void pushDataToQueue(const BYTE * pbData, DWORD dwDataSize, bool fromHost = true);
	static void addIncomingSocket(Socket *socket);
	InputStream *getInputStream(bool isServerConnection);
	void setSoTimeout(int a );
	void setTrafficClass( int a );
	SocketOutputStream *getOutputStream(bool isServerConnection);
	bool close(bool isServerConnection);
	bool createdOk;
	bool isLocal() { return m_hostLocal; }

	bool isClosing() { return m_endClosed[SOCKET_CLIENT_END] || m_endClosed[SOCKET_SERVER_END]; }
	BYTE getSmallId() { return networkPlayerSmallId; }
};