aboutsummaryrefslogtreecommitdiff
path: root/util/buildbot/buildwin64.sh
blob: 54bfbef69e1bc260613dbb8864a5a4ce9dc86dc5 (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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#!/bin/bash
set -e

CORE_GIT=https://github.com/minetest/minetest
CORE_BRANCH=master
CORE_NAME=minetest
GAME_GIT=https://github.com/minetest/minetest_game
GAME_BRANCH=master
GAME_NAME=minetest_game

dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ $# -ne 1 ]; then
	echo "Usage: $0 <build directory>"
	exit 1
fi
builddir=$1
mkdir -p $builddir
builddir="$( cd "$builddir" && pwd )"
packagedir=$builddir/packages
libdir=$builddir/libs

toolchain_file=$dir/toolchain_x86_64-w64-mingw32.cmake
irrlicht_version=1.9.0mt1
ogg_version=1.3.2
vorbis_version=1.3.5
curl_version=7.65.3
gettext_version=0.20.1
freetype_version=2.10.1
sqlite3_version=3.27.2
luajit_version=2.1.0-beta3
leveldb_version=1.22
zlib_version=1.2.11

mkdir -p $packagedir
mkdir -p $libdir

cd $builddir

# Get stuff
[ -e $packagedir/irrlicht-$irrlicht_version.zip ] || wget https://github.com/minetest/irrlicht/releases/download/$irrlicht_version/win64.zip \
	-c -O $packagedir/irrlicht-$irrlicht_version.zip
[ -e $packagedir/zlib-$zlib_version.zip ] || wget http://minetest.kitsunemimi.pw/zlib-$zlib_version-win64.zip \
	-c -O $packagedir/zlib-$zlib_version.zip
[ -e $packagedir/libogg-$ogg_version.zip ] || wget http://minetest.kitsunemimi.pw/libogg-$ogg_version-win64.zip \
	-c -O $packagedir/libogg-$ogg_version.zip
[ -e $packagedir/libvorbis-$vorbis_version.zip ] || wget http://minetest.kitsunemimi.pw/libvorbis-$vorbis_version-win64.zip \
	-c -O $packagedir/libvorbis-$vorbis_version.zip
[ -e $packagedir/curl-$curl_version.zip ] || wget http://minetest.kitsunemimi.pw/curl-$curl_version-win64.zip \
	-c -O $packagedir/curl-$curl_version.zip
[ -e $packagedir/gettext-$gettext_version.zip ] || wget http://minetest.kitsunemimi.pw/gettext-$gettext_version-win64.zip \
	-c -O $packagedir/gettext-$gettext_version.zip
[ -e $packagedir/freetype2-$freetype_version.zip ] || wget http://minetest.kitsunemimi.pw/freetype2-$freetype_version-win64.zip \
	-c -O $packagedir/freetype2-$freetype_version.zip
[ -e $packagedir/sqlite3-$sqlite3_version.zip ] || wget http://minetest.kitsunemimi.pw/sqlite3-$sqlite3_version-win64.zip \
	-c -O $packagedir/sqlite3-$sqlite3_version.zip
[ -e $packagedir/luajit-$luajit_version.zip ] || wget http://minetest.kitsunemimi.pw/luajit-$luajit_version-win64.zip \
	-c -O $packagedir/luajit-$luajit_version.zip
[ -e $packagedir/libleveldb-$leveldb_version.zip ] || wget http://minetest.kitsunemimi.pw/libleveldb-$leveldb_version-win64.zip \
	-c -O $packagedir/libleveldb-$leveldb_version.zip
[ -e $packagedir/openal_stripped.zip ] || wget http://minetest.kitsunemimi.pw/openal_stripped64.zip \
	-c -O $packagedir/openal_stripped.zip


# Extract stuff
cd $libdir
[ -d irrlicht ] || unzip -o $packagedir/irrlicht-$irrlicht_version.zip -d irrlicht
[ -d zlib ] || unzip -o $packagedir/zlib-$zlib_version.zip -d zlib
[ -d libogg ] || unzip -o $packagedir/libogg-$ogg_version.zip -d libogg
[ -d libvorbis ] || unzip -o $packagedir/libvorbis-$vorbis_version.zip -d libvorbis
[ -d libcurl ] || unzip -o $packagedir/curl-$curl_version.zip -d libcurl
[ -d gettext ] || unzip -o $packagedir/gettext-$gettext_version.zip -d gettext
[ -d freetype ] || unzip -o $packagedir/freetype2-$freetype_version.zip -d freetype
[ -d sqlite3 ] || unzip -o $packagedir/sqlite3-$sqlite3_version.zip -d sqlite3
[ -d openal_stripped ] || unzip -o $packagedir/openal_stripped.zip
[ -d luajit ] || unzip -o $packagedir/luajit-$luajit_version.zip -d luajit
[ -d leveldb ] || unzip -o $packagedir/libleveldb-$leveldb_version.zip -d leveldb

# Get minetest
cd $builddir
if [ ! "x$EXISTING_MINETEST_DIR" = "x" ]; then
	cd /$EXISTING_MINETEST_DIR # must be absolute path
else
	[ -d $CORE_NAME ] && (cd $CORE_NAME && git pull) || (git clone -b $CORE_BRANCH $CORE_GIT)
	cd $CORE_NAME
fi
git_hash=$(git rev-parse --short HEAD)

# Get minetest_game
if [ "x$NO_MINETEST_GAME" = "x" ]; then
	cd games
	[ -d $GAME_NAME ] && (cd $GAME_NAME && git pull) || (git clone -b $GAME_BRANCH $GAME_GIT)
	cd ..
fi

irr_dlls=$(echo $libdir/irrlicht/bin/*.dll | tr ' ' ';')
vorbis_dlls=$(echo $libdir/libvorbis/bin/libvorbis{,file}-*.dll | tr ' ' ';')
gettext_dlls=$(echo $libdir/gettext/bin/lib{intl,iconv}-*.dll | tr ' ' ';')

# Build the thing
[ -d _build ] && rm -Rf _build/
mkdir _build
cd _build
cmake .. \
	-DCMAKE_TOOLCHAIN_FILE=$toolchain_file \
	-DCMAKE_INSTALL_PREFIX=/tmp \
	-DVERSION_EXTRA=$git_hash \
	-DBUILD_CLIENT=1 -DBUILD_SERVER=0 \
	\
	-DENABLE_SOUND=1 \
	-DENABLE_CURL=1 \
	-DENABLE_GETTEXT=1 \
	-DENABLE_FREETYPE=1 \
	-DENABLE_LEVELDB=1 \
	\
	-DIRRLICHT_INCLUDE_DIR=$libdir/irrlicht/include/irrlichtmt \
	-DIRRLICHT_LIBRARY=$libdir/irrlicht/lib/libIrrlichtMt.dll.a \
	-DIRRLICHT_DLL="$irr_dlls" \
	\
	-DZLIB_INCLUDE_DIR=$libdir/zlib/include \
	-DZLIB_LIBRARIES=$libdir/zlib/lib/libz.dll.a \
	-DZLIB_DLL=$libdir/zlib/bin/zlib1.dll \
	\
	-DLUA_INCLUDE_DIR=$libdir/luajit/include \
	-DLUA_LIBRARY=$libdir/luajit/libluajit.a \
	\
	-DOGG_INCLUDE_DIR=$libdir/libogg/include \
	-DOGG_LIBRARY=$libdir/libogg/lib/libogg.dll.a \
	-DOGG_DLL=$libdir/libogg/bin/libogg-0.dll \
	\
	-DVORBIS_INCLUDE_DIR=$libdir/libvorbis/include \
	-DVORBIS_LIBRARY=$libdir/libvorbis/lib/libvorbis.dll.a \
	-DVORBIS_DLL="$vorbis_dlls" \
	-DVORBISFILE_LIBRARY=$libdir/libvorbis/lib/libvorbisfile.dll.a \
	\
	-DOPENAL_INCLUDE_DIR=$libdir/openal_stripped/include/AL \
	-DOPENAL_LIBRARY=$libdir/openal_stripped/lib/libOpenAL32.dll.a \
	-DOPENAL_DLL=$libdir/openal_stripped/bin/OpenAL32.dll \
	\
	-DCURL_DLL=$libdir/libcurl/bin/libcurl-4.dll \
	-DCURL_INCLUDE_DIR=$libdir/libcurl/include \
	-DCURL_LIBRARY=$libdir/libcurl/lib/libcurl.dll.a \
	\
	-DGETTEXT_MSGFMT=`which msgfmt` \
	-DGETTEXT_DLL="$gettext_dlls" \
	-DGETTEXT_INCLUDE_DIR=$libdir/gettext/include \
	-DGETTEXT_LIBRARY=$libdir/gettext/lib/libintl.dll.a \
	\
	-DFREETYPE_INCLUDE_DIR_freetype2=$libdir/freetype/include/freetype2 \
	-DFREETYPE_INCLUDE_DIR_ft2build=$libdir/freetype/include/freetype2 \
	-DFREETYPE_LIBRARY=$libdir/freetype/lib/libfreetype.dll.a \
	-DFREETYPE_DLL=$libdir/freetype/bin/libfreetype-6.dll \
	\
	-DSQLITE3_INCLUDE_DIR=$libdir/sqlite3/include \
	-DSQLITE3_LIBRARY=$libdir/sqlite3/lib/libsqlite3.dll.a \
	-DSQLITE3_DLL=$libdir/sqlite3/bin/libsqlite3-0.dll \
	\
	-DLEVELDB_INCLUDE_DIR=$libdir/leveldb/include \
	-DLEVELDB_LIBRARY=$libdir/leveldb/lib/libleveldb.dll.a \
	-DLEVELDB_DLL=$libdir/leveldb/bin/libleveldb.dll

make -j$(nproc)

[ "x$NO_PACKAGE" = "x" ] && make package

exit 0
# EOF
s &address, SharedBuffer<u8> &data, u32 protocol_id, u16 sender_peer_id, u8 channel); // Add the TYPE_ORIGINAL header to the data SharedBuffer<u8> makeOriginalPacket( SharedBuffer<u8> data); // Split data in chunks and add TYPE_SPLIT headers to them core::list<SharedBuffer<u8> > makeSplitPacket( SharedBuffer<u8> data, u32 chunksize_max, u16 seqnum); // Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet // Increments split_seqnum if a split packet is made core::list<SharedBuffer<u8> > makeAutoSplitPacket( SharedBuffer<u8> data, u32 chunksize_max, u16 &split_seqnum); // Add the TYPE_RELIABLE header to the data SharedBuffer<u8> makeReliablePacket( SharedBuffer<u8> data, u16 seqnum); struct IncomingSplitPacket { IncomingSplitPacket() { time = 0.0; reliable = false; } // Key is chunk number, value is data without headers core::map<u16, SharedBuffer<u8> > chunks; u32 chunk_count; float time; // Seconds from adding bool reliable; // If true, isn't deleted on timeout bool allReceived() { return (chunks.size() == chunk_count); } }; /* === NOTES === A packet is sent through a channel to a peer with a basic header: TODO: Should we have a receiver_peer_id also? Header (7 bytes): [0] u32 protocol_id [4] u16 sender_peer_id [6] u8 channel sender_peer_id: Unique to each peer. value 0 is reserved for making new connections value 1 is reserved for server channel: The lower the number, the higher the priority is. Only channels 0, 1 and 2 exist. */ #define BASE_HEADER_SIZE 7 #define PEER_ID_INEXISTENT 0 #define PEER_ID_SERVER 1 #define CHANNEL_COUNT 3 /* Packet types: CONTROL: This is a packet used by the protocol. - When this is processed, nothing is handed to the user. Header (2 byte): [0] u8 type [1] u8 controltype controltype and data description: CONTROLTYPE_ACK [2] u16 seqnum CONTROLTYPE_SET_PEER_ID [2] u16 peer_id_new CONTROLTYPE_PING - There is no actual reply, but this can be sent in a reliable packet to get a reply CONTROLTYPE_DISCO */ #define TYPE_CONTROL 0 #define CONTROLTYPE_ACK 0 #define CONTROLTYPE_SET_PEER_ID 1 #define CONTROLTYPE_PING 2 #define CONTROLTYPE_DISCO 3 /* ORIGINAL: This is a plain packet with no control and no error checking at all. - When this is processed, it is directly handed to the user. Header (1 byte): [0] u8 type */ #define TYPE_ORIGINAL 1 #define ORIGINAL_HEADER_SIZE 1 /* SPLIT: These are sequences of packets forming one bigger piece of data. - When processed and all the packet_nums 0...packet_count-1 are present (this should be buffered), the resulting data shall be directly handed to the user. - If the data fails to come up in a reasonable time, the buffer shall be silently discarded. - These can be sent as-is or atop of a RELIABLE packet stream. Header (7 bytes): [0] u8 type [1] u16 seqnum [3] u16 chunk_count [5] u16 chunk_num */ #define TYPE_SPLIT 2 /* RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs, and they shall be delivered in the same order as sent. This is done with a buffer in the receiving and transmitting end. - When this is processed, the contents of each packet is recursively processed as packets. Header (3 bytes): [0] u8 type [1] u16 seqnum */ #define TYPE_RELIABLE 3 #define RELIABLE_HEADER_SIZE 3 //#define SEQNUM_INITIAL 0x10 #define SEQNUM_INITIAL 65500 /* A buffer which stores reliable packets and sorts them internally for fast access to the smallest one. */ typedef core::list<BufferedPacket>::Iterator RPBSearchResult; class ReliablePacketBuffer { public: void print(); bool empty(); u32 size(); RPBSearchResult findPacket(u16 seqnum); RPBSearchResult notFound(); u16 getFirstSeqnum(); BufferedPacket popFirst(); BufferedPacket popSeqnum(u16 seqnum); void insert(BufferedPacket &p); void incrementTimeouts(float dtime); void resetTimedOuts(float timeout); bool anyTotaltimeReached(float timeout); core::list<BufferedPacket> getTimedOuts(float timeout); private: core::list<BufferedPacket> m_list; }; /* A buffer for reconstructing split packets */ class IncomingSplitBuffer { public: ~IncomingSplitBuffer(); /* Returns a reference counted buffer of length != 0 when a full split packet is constructed. If not, returns one of length 0. */ SharedBuffer<u8> insert(BufferedPacket &p, bool reliable); void removeUnreliableTimedOuts(float dtime, float timeout); private: // Key is seqnum core::map<u16, IncomingSplitPacket*> m_buf; }; class Connection; struct Channel { Channel(); ~Channel(); u16 next_outgoing_seqnum; u16 next_incoming_seqnum; u16 next_outgoing_split_seqnum; // This is for buffering the incoming packets that are coming in // the wrong order ReliablePacketBuffer incoming_reliables; // This is for buffering the sent packets so that the sender can // re-send them if no ACK is received ReliablePacketBuffer outgoing_reliables; IncomingSplitBuffer incoming_splits; }; class Peer; class PeerHandler { public: PeerHandler() { } virtual ~PeerHandler() { } /* This is called after the Peer has been inserted into the Connection's peer container. */ virtual void peerAdded(Peer *peer) = 0; /* This is called before the Peer has been removed from the Connection's peer container. */ virtual void deletingPeer(Peer *peer, bool timeout) = 0; }; class Peer { public: Peer(u16 a_id, Address a_address); virtual ~Peer(); /* Calculates avg_rtt and resend_timeout. rtt=-1 only recalculates resend_timeout */ void reportRTT(float rtt); Channel channels[CHANNEL_COUNT]; // Address of the peer Address address; // Unique id of the peer u16 id; // Seconds from last receive float timeout_counter; // Ping timer float ping_timer; // This is changed dynamically float resend_timeout; // Updated when an ACK is received float avg_rtt; // This is set to true when the peer has actually sent something // with the id we have given to it bool has_sent_with_id; float m_sendtime_accu; float m_max_packets_per_second; int m_num_sent; int m_max_num_sent; private: }; /* Connection */ struct OutgoingPacket { u16 peer_id; u8 channelnum; SharedBuffer<u8> data; bool reliable; OutgoingPacket(u16 peer_id_, u8 channelnum_, SharedBuffer<u8> data_, bool reliable_): peer_id(peer_id_), channelnum(channelnum_), data(data_), reliable(reliable_) { } }; enum ConnectionEventType{ CONNEVENT_NONE, CONNEVENT_DATA_RECEIVED, CONNEVENT_PEER_ADDED, CONNEVENT_PEER_REMOVED, CONNEVENT_BIND_FAILED, }; struct ConnectionEvent { enum ConnectionEventType type; u16 peer_id; Buffer<u8> data; bool timeout; Address address; ConnectionEvent(): type(CONNEVENT_NONE) {} std::string describe() { switch(type){ case CONNEVENT_NONE: return "CONNEVENT_NONE"; case CONNEVENT_DATA_RECEIVED: return "CONNEVENT_DATA_RECEIVED"; case CONNEVENT_PEER_ADDED: return "CONNEVENT_PEER_ADDED"; case CONNEVENT_PEER_REMOVED: return "CONNEVENT_PEER_REMOVED"; case CONNEVENT_BIND_FAILED: return "CONNEVENT_BIND_FAILED"; } return "Invalid ConnectionEvent"; } void dataReceived(u16 peer_id_, SharedBuffer<u8> data_) { type = CONNEVENT_DATA_RECEIVED; peer_id = peer_id_; data = data_; } void peerAdded(u16 peer_id_, Address address_) { type = CONNEVENT_PEER_ADDED; peer_id = peer_id_; address = address_; } void peerRemoved(u16 peer_id_, bool timeout_, Address address_) { type = CONNEVENT_PEER_REMOVED; peer_id = peer_id_; timeout = timeout_; address = address_; } void bindFailed() { type = CONNEVENT_BIND_FAILED; } }; enum ConnectionCommandType{ CONNCMD_NONE, CONNCMD_SERVE, CONNCMD_CONNECT, CONNCMD_DISCONNECT, CONNCMD_SEND, CONNCMD_SEND_TO_ALL, CONNCMD_DELETE_PEER, }; struct ConnectionCommand { enum ConnectionCommandType type; u16 port; Address address; u16 peer_id; u8 channelnum; Buffer<u8> data; bool reliable; ConnectionCommand(): type(CONNCMD_NONE) {} void serve(u16 port_) { type = CONNCMD_SERVE; port = port_; } void connect(Address address_) { type = CONNCMD_CONNECT; address = address_; } void disconnect() { type = CONNCMD_DISCONNECT; } void send(u16 peer_id_, u8 channelnum_, SharedBuffer<u8> data_, bool reliable_) { type = CONNCMD_SEND; peer_id = peer_id_; channelnum = channelnum_; data = data_; reliable = reliable_; } void sendToAll(u8 channelnum_, SharedBuffer<u8> data_, bool reliable_) { type = CONNCMD_SEND_TO_ALL; channelnum = channelnum_; data = data_; reliable = reliable_; } void deletePeer(u16 peer_id_) { type = CONNCMD_DELETE_PEER; peer_id = peer_id_; } }; class Connection: public SimpleThread { public: Connection(u32 protocol_id, u32 max_packet_size, float timeout); Connection(u32 protocol_id, u32 max_packet_size, float timeout, PeerHandler *peerhandler); ~Connection(); void * Thread(); /* Interface */ ConnectionEvent getEvent(); ConnectionEvent waitEvent(u32 timeout_ms); void putCommand(ConnectionCommand &c); void SetTimeoutMs(int timeout){ m_bc_receive_timeout = timeout; } void Serve(unsigned short port); void Connect(Address address); bool Connected(); void Disconnect(); u32 Receive(u16 &peer_id, SharedBuffer<u8> &data); void SendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable); void Send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable); void RunTimeouts(float dtime); // dummy u16 GetPeerID(){ return m_peer_id; } Address GetPeerAddress(u16 peer_id); float GetPeerAvgRTT(u16 peer_id); void DeletePeer(u16 peer_id); private: void putEvent(ConnectionEvent &e); void processCommand(ConnectionCommand &c); void send(float dtime); void receive(); void runTimeouts(float dtime); void serve(u16 port); void connect(Address address); void disconnect(); void sendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable); void send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable); void sendAsPacket(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable); void rawSendAsPacket(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable); void rawSend(const BufferedPacket &packet); Peer* getPeer(u16 peer_id); Peer* getPeerNoEx(u16 peer_id); core::list<Peer*> getPeers(); bool getFromBuffers(u16 &peer_id, SharedBuffer<u8> &dst); // Returns next data from a buffer if possible // If found, returns true; if not, false. // If found, sets peer_id and dst bool checkIncomingBuffers(Channel *channel, u16 &peer_id, SharedBuffer<u8> &dst); /* Processes a packet with the basic header stripped out. Parameters: packetdata: Data in packet (with no base headers) peer_id: peer id of the sender of the packet in question channelnum: channel on which the packet was sent reliable: true if recursing into a reliable packet */ SharedBuffer<u8> processPacket(Channel *channel, SharedBuffer<u8> packetdata, u16 peer_id, u8 channelnum, bool reliable); bool deletePeer(u16 peer_id, bool timeout); Queue<OutgoingPacket> m_outgoing_queue; MutexedQueue<ConnectionEvent> m_event_queue; MutexedQueue<ConnectionCommand> m_command_queue; u32 m_protocol_id; u32 m_max_packet_size; float m_timeout; UDPSocket m_socket; u16 m_peer_id; core::map<u16, Peer*> m_peers; JMutex m_peers_mutex; // Backwards compatibility PeerHandler *m_bc_peerhandler; int m_bc_receive_timeout; void SetPeerID(u16 id){ m_peer_id = id; } u32 GetProtocolID(){ return m_protocol_id; } void PrintInfo(std::ostream &out); void PrintInfo(); std::string getDesc(); u16 m_indentation; }; } // namespace #endif