mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 17:50:22 +00:00
Added Game Maker Language
This commit is contained in:
@@ -580,6 +580,11 @@ Forth:
|
|||||||
extensions:
|
extensions:
|
||||||
- .4th
|
- .4th
|
||||||
|
|
||||||
|
Game Maker Language:
|
||||||
|
type: programming
|
||||||
|
lexer: JavaScript
|
||||||
|
primary_extension: .gml
|
||||||
|
|
||||||
GAS:
|
GAS:
|
||||||
type: programming
|
type: programming
|
||||||
group: Assembly
|
group: Assembly
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
642
samples/Game Maker Language/ClientBeginStep.gml
Normal file
642
samples/Game Maker Language/ClientBeginStep.gml
Normal file
@@ -0,0 +1,642 @@
|
|||||||
|
/*
|
||||||
|
Originally from /Source/gg2/Scripts/Client/ClientBeginStep.gml in Gang Garrison 2
|
||||||
|
|
||||||
|
Copyright (C) 2008-2013 Faucet Software
|
||||||
|
http://www.ganggarrison.com
|
||||||
|
|
||||||
|
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>.
|
||||||
|
|
||||||
|
Additional permission under GNU GPL version 3 section 7
|
||||||
|
If you modify this Program, or any covered work, by linking or combining it with the Game Maker runtime library,
|
||||||
|
the 39dll library/extension, Hobbel's Download Manager DLL, or modified versions of these libraries,
|
||||||
|
the licensors of this Program grant you additional permission to convey the resulting work.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// receive and interpret the server's message(s)
|
||||||
|
var i, playerObject, playerID, player, otherPlayerID, otherPlayer, sameVersion, buffer, plugins, pluginsRequired, usePlugins;
|
||||||
|
|
||||||
|
if(tcp_eof(global.serverSocket)) {
|
||||||
|
if(gotServerHello)
|
||||||
|
show_message("You have been disconnected from the server.");
|
||||||
|
else
|
||||||
|
show_message("Unable to connect to the server.");
|
||||||
|
instance_destroy();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(room == DownloadRoom and keyboard_check(vk_escape))
|
||||||
|
{
|
||||||
|
instance_destroy();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(downloadingMap)
|
||||||
|
{
|
||||||
|
while(tcp_receive(global.serverSocket, min(1024, downloadMapBytes-buffer_size(downloadMapBuffer))))
|
||||||
|
{
|
||||||
|
write_buffer(downloadMapBuffer, global.serverSocket);
|
||||||
|
if(buffer_size(downloadMapBuffer) == downloadMapBytes)
|
||||||
|
{
|
||||||
|
write_buffer_to_file(downloadMapBuffer, "Maps/" + downloadMapName + ".png");
|
||||||
|
downloadingMap = false;
|
||||||
|
buffer_destroy(downloadMapBuffer);
|
||||||
|
downloadMapBuffer = -1;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
roomchange = false;
|
||||||
|
do {
|
||||||
|
if(tcp_receive(global.serverSocket,1)) {
|
||||||
|
switch(read_ubyte(global.serverSocket)) {
|
||||||
|
case HELLO:
|
||||||
|
gotServerHello = true;
|
||||||
|
global.joinedServerName = receivestring(global.serverSocket, 1);
|
||||||
|
downloadMapName = receivestring(global.serverSocket, 1);
|
||||||
|
advertisedMapMd5 = receivestring(global.serverSocket, 1);
|
||||||
|
receiveCompleteMessage(global.serverSocket, 1, global.tempBuffer);
|
||||||
|
pluginsRequired = read_ubyte(global.tempBuffer);
|
||||||
|
plugins = receivestring(global.serverSocket, 1);
|
||||||
|
if(string_pos("/", downloadMapName) != 0 or string_pos("\", downloadMapName) != 0)
|
||||||
|
{
|
||||||
|
show_message("Server sent illegal map name: "+downloadMapName);
|
||||||
|
instance_destroy();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!noReloadPlugins && string_length(plugins))
|
||||||
|
{
|
||||||
|
usePlugins = pluginsRequired || !global.serverPluginsPrompt;
|
||||||
|
if (global.serverPluginsPrompt)
|
||||||
|
{
|
||||||
|
var prompt;
|
||||||
|
if (pluginsRequired)
|
||||||
|
{
|
||||||
|
prompt = show_question(
|
||||||
|
"This server requires the following plugins to play on it: "
|
||||||
|
+ string_replace_all(plugins, ",", "#")
|
||||||
|
+ '#They are downloaded from the source: "'
|
||||||
|
+ PLUGIN_SOURCE
|
||||||
|
+ '"#The source states: "'
|
||||||
|
+ PLUGIN_SOURCE_NOTICE
|
||||||
|
+ '"#Do you wish to download them and continue connecting?'
|
||||||
|
);
|
||||||
|
if (!prompt)
|
||||||
|
{
|
||||||
|
instance_destroy();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prompt = show_question(
|
||||||
|
"This server suggests the following optional plugins to play on it: "
|
||||||
|
+ string_replace_all(plugins, ",", "#")
|
||||||
|
+ '#They are downloaded from the source: "'
|
||||||
|
+ PLUGIN_SOURCE
|
||||||
|
+ '"#The source states: "'
|
||||||
|
+ PLUGIN_SOURCE_NOTICE
|
||||||
|
+ '"#Do you wish to download them and use them?'
|
||||||
|
);
|
||||||
|
if (prompt)
|
||||||
|
{
|
||||||
|
usePlugins = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (usePlugins)
|
||||||
|
{
|
||||||
|
if (!loadserverplugins(plugins))
|
||||||
|
{
|
||||||
|
show_message("Error ocurred loading server-sent plugins.");
|
||||||
|
instance_destroy();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
global.serverPluginsInUse = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
noReloadPlugins = false;
|
||||||
|
|
||||||
|
if(advertisedMapMd5 != "")
|
||||||
|
{
|
||||||
|
var download;
|
||||||
|
download = not file_exists("Maps/" + downloadMapName + ".png");
|
||||||
|
if(!download and CustomMapGetMapMD5(downloadMapName) != advertisedMapMd5)
|
||||||
|
{
|
||||||
|
if(show_question("The server's copy of the map (" + downloadMapName + ") differs from ours.#Would you like to download this server's version of the map?"))
|
||||||
|
download = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
instance_destroy();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(download)
|
||||||
|
{
|
||||||
|
write_ubyte(global.serverSocket, DOWNLOAD_MAP);
|
||||||
|
socket_send(global.serverSocket);
|
||||||
|
receiveCompleteMessage(global.serverSocket,4,global.tempBuffer);
|
||||||
|
downloadMapBytes = read_uint(global.tempBuffer);
|
||||||
|
downloadMapBuffer = buffer_create();
|
||||||
|
downloadingMap = true;
|
||||||
|
roomchange=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ClientPlayerJoin(global.serverSocket);
|
||||||
|
if(global.rewardKey != "" and global.rewardId != "")
|
||||||
|
{
|
||||||
|
var rewardId;
|
||||||
|
rewardId = string_copy(global.rewardId, 0, 255);
|
||||||
|
write_ubyte(global.serverSocket, REWARD_REQUEST);
|
||||||
|
write_ubyte(global.serverSocket, string_length(rewardId));
|
||||||
|
write_string(global.serverSocket, rewardId);
|
||||||
|
}
|
||||||
|
if(global.queueJumping == true)
|
||||||
|
{
|
||||||
|
write_ubyte(global.serverSocket, CLIENT_SETTINGS);
|
||||||
|
write_ubyte(global.serverSocket, global.queueJumping);
|
||||||
|
}
|
||||||
|
socket_send(global.serverSocket);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JOIN_UPDATE:
|
||||||
|
receiveCompleteMessage(global.serverSocket,2,global.tempBuffer);
|
||||||
|
global.playerID = read_ubyte(global.tempBuffer);
|
||||||
|
global.currentMapArea = read_ubyte(global.tempBuffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FULL_UPDATE:
|
||||||
|
deserializeState(FULL_UPDATE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QUICK_UPDATE:
|
||||||
|
deserializeState(QUICK_UPDATE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CAPS_UPDATE:
|
||||||
|
deserializeState(CAPS_UPDATE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INPUTSTATE:
|
||||||
|
deserializeState(INPUTSTATE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLAYER_JOIN:
|
||||||
|
player = instance_create(0,0,Player);
|
||||||
|
player.name = receivestring(global.serverSocket, 1);
|
||||||
|
|
||||||
|
ds_list_add(global.players, player);
|
||||||
|
if(ds_list_size(global.players)-1 == global.playerID) {
|
||||||
|
global.myself = player;
|
||||||
|
instance_create(0,0,PlayerControl);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLAYER_LEAVE:
|
||||||
|
// Delete player from the game, adjust own ID accordingly
|
||||||
|
receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
|
||||||
|
playerID = read_ubyte(global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, playerID);
|
||||||
|
removePlayer(player);
|
||||||
|
if(playerID < global.playerID) {
|
||||||
|
global.playerID -= 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLAYER_DEATH:
|
||||||
|
var causeOfDeath, assistantPlayerID, assistantPlayer;
|
||||||
|
receiveCompleteMessage(global.serverSocket,4,global.tempBuffer);
|
||||||
|
playerID = read_ubyte(global.tempBuffer);
|
||||||
|
otherPlayerID = read_ubyte(global.tempBuffer);
|
||||||
|
assistantPlayerID = read_ubyte(global.tempBuffer);
|
||||||
|
causeOfDeath = read_ubyte(global.tempBuffer);
|
||||||
|
|
||||||
|
player = ds_list_find_value(global.players, playerID);
|
||||||
|
|
||||||
|
otherPlayer = noone;
|
||||||
|
if(otherPlayerID != 255)
|
||||||
|
otherPlayer = ds_list_find_value(global.players, otherPlayerID);
|
||||||
|
|
||||||
|
assistantPlayer = noone;
|
||||||
|
if(assistantPlayerID != 255)
|
||||||
|
assistantPlayer = ds_list_find_value(global.players, assistantPlayerID);
|
||||||
|
|
||||||
|
doEventPlayerDeath(player, otherPlayer, assistantPlayer, causeOfDeath);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BALANCE:
|
||||||
|
receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
|
||||||
|
balanceplayer=read_ubyte(global.tempBuffer);
|
||||||
|
if balanceplayer == 255 {
|
||||||
|
if !instance_exists(Balancer) instance_create(x,y,Balancer);
|
||||||
|
with(Balancer) notice=0;
|
||||||
|
} else {
|
||||||
|
player = ds_list_find_value(global.players, balanceplayer);
|
||||||
|
if(player.object != -1) {
|
||||||
|
with(player.object) {
|
||||||
|
instance_destroy();
|
||||||
|
}
|
||||||
|
player.object = -1;
|
||||||
|
}
|
||||||
|
if(player.team==TEAM_RED) {
|
||||||
|
player.team = TEAM_BLUE;
|
||||||
|
} else {
|
||||||
|
player.team = TEAM_RED;
|
||||||
|
}
|
||||||
|
if !instance_exists(Balancer) instance_create(x,y,Balancer);
|
||||||
|
Balancer.name=player.name;
|
||||||
|
with (Balancer) notice=1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLAYER_CHANGETEAM:
|
||||||
|
receiveCompleteMessage(global.serverSocket,2,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
if(player.object != -1) {
|
||||||
|
with(player.object) {
|
||||||
|
instance_destroy();
|
||||||
|
}
|
||||||
|
player.object = -1;
|
||||||
|
}
|
||||||
|
player.team = read_ubyte(global.tempBuffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLAYER_CHANGECLASS:
|
||||||
|
receiveCompleteMessage(global.serverSocket,2,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
if(player.object != -1) {
|
||||||
|
with(player.object) {
|
||||||
|
instance_destroy();
|
||||||
|
}
|
||||||
|
player.object = -1;
|
||||||
|
}
|
||||||
|
player.class = read_ubyte(global.tempBuffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLAYER_CHANGENAME:
|
||||||
|
receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
player.name = receivestring(global.serverSocket, 1);
|
||||||
|
if player=global.myself {
|
||||||
|
global.playerName=player.name
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLAYER_SPAWN:
|
||||||
|
receiveCompleteMessage(global.serverSocket,3,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
doEventSpawn(player, read_ubyte(global.tempBuffer), read_ubyte(global.tempBuffer));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CHAT_BUBBLE:
|
||||||
|
var bubbleImage;
|
||||||
|
receiveCompleteMessage(global.serverSocket,2,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
setChatBubble(player, read_ubyte(global.tempBuffer));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BUILD_SENTRY:
|
||||||
|
receiveCompleteMessage(global.serverSocket,6,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
buildSentry(player, read_ushort(global.tempBuffer)/5, read_ushort(global.tempBuffer)/5, read_byte(global.tempBuffer));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DESTROY_SENTRY:
|
||||||
|
receiveCompleteMessage(global.serverSocket,4,global.tempBuffer);
|
||||||
|
playerID = read_ubyte(global.tempBuffer);
|
||||||
|
otherPlayerID = read_ubyte(global.tempBuffer);
|
||||||
|
assistantPlayerID = read_ubyte(global.tempBuffer);
|
||||||
|
causeOfDeath = read_ubyte(global.tempBuffer);
|
||||||
|
|
||||||
|
player = ds_list_find_value(global.players, playerID);
|
||||||
|
if(otherPlayerID == 255) {
|
||||||
|
doEventDestruction(player, noone, noone, causeOfDeath);
|
||||||
|
} else {
|
||||||
|
otherPlayer = ds_list_find_value(global.players, otherPlayerID);
|
||||||
|
if (assistantPlayerID == 255) {
|
||||||
|
doEventDestruction(player, otherPlayer, noone, causeOfDeath);
|
||||||
|
} else {
|
||||||
|
assistantPlayer = ds_list_find_value(global.players, assistantPlayerID);
|
||||||
|
doEventDestruction(player, otherPlayer, assistantPlayer, causeOfDeath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GRAB_INTEL:
|
||||||
|
receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
doEventGrabIntel(player);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCORE_INTEL:
|
||||||
|
receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
doEventScoreIntel(player);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DROP_INTEL:
|
||||||
|
receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
doEventDropIntel(player);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RETURN_INTEL:
|
||||||
|
receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
|
||||||
|
doEventReturnIntel(read_ubyte(global.tempBuffer));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GENERATOR_DESTROY:
|
||||||
|
receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
|
||||||
|
team = read_ubyte(global.tempBuffer);
|
||||||
|
doEventGeneratorDestroy(team);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UBER_CHARGED:
|
||||||
|
receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
doEventUberReady(player);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UBER:
|
||||||
|
receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
doEventUber(player);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OMNOMNOMNOM:
|
||||||
|
receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
if(player.object != -1) {
|
||||||
|
with(player.object) {
|
||||||
|
omnomnomnom=true;
|
||||||
|
if(hp < 200)
|
||||||
|
{
|
||||||
|
canEat = false;
|
||||||
|
alarm[6] = eatCooldown; //10 second cooldown
|
||||||
|
}
|
||||||
|
if(player.team == TEAM_RED) {
|
||||||
|
omnomnomnomindex=0;
|
||||||
|
omnomnomnomend=31;
|
||||||
|
} else if(player.team==TEAM_BLUE) {
|
||||||
|
omnomnomnomindex=32;
|
||||||
|
omnomnomnomend=63;
|
||||||
|
}
|
||||||
|
xscale=image_xscale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TOGGLE_ZOOM:
|
||||||
|
receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
if player.object != -1 {
|
||||||
|
toggleZoom(player.object);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PASSWORD_REQUEST:
|
||||||
|
if(!usePreviousPwd)
|
||||||
|
global.clientPassword = get_string("Enter Password:", "");
|
||||||
|
write_ubyte(global.serverSocket, string_length(global.clientPassword));
|
||||||
|
write_string(global.serverSocket, global.clientPassword);
|
||||||
|
socket_send(global.serverSocket);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PASSWORD_WRONG:
|
||||||
|
show_message("Incorrect Password.");
|
||||||
|
instance_destroy();
|
||||||
|
exit;
|
||||||
|
|
||||||
|
case INCOMPATIBLE_PROTOCOL:
|
||||||
|
show_message("Incompatible server protocol version.");
|
||||||
|
instance_destroy();
|
||||||
|
exit;
|
||||||
|
|
||||||
|
case KICK:
|
||||||
|
receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
|
||||||
|
reason = read_ubyte(global.tempBuffer);
|
||||||
|
if reason == KICK_NAME kickReason = "Name Exploit";
|
||||||
|
else if reason == KICK_BAD_PLUGIN_PACKET kickReason = "Invalid plugin packet ID";
|
||||||
|
else if reason == KICK_MULTI_CLIENT kickReason = "There are too many connections from your IP";
|
||||||
|
else kickReason = "";
|
||||||
|
show_message("You have been kicked from the server. "+kickReason+".");
|
||||||
|
instance_destroy();
|
||||||
|
exit;
|
||||||
|
|
||||||
|
case ARENA_STARTROUND:
|
||||||
|
doEventArenaStartRound();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARENA_ENDROUND:
|
||||||
|
with ArenaHUD clientArenaEndRound();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARENA_RESTART:
|
||||||
|
doEventArenaRestart();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UNLOCKCP:
|
||||||
|
doEventUnlockCP();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAP_END:
|
||||||
|
global.nextMap=receivestring(global.serverSocket, 1);
|
||||||
|
receiveCompleteMessage(global.serverSocket,2,global.tempBuffer);
|
||||||
|
global.winners=read_ubyte(global.tempBuffer);
|
||||||
|
global.currentMapArea=read_ubyte(global.tempBuffer);
|
||||||
|
global.mapchanging = true;
|
||||||
|
if !instance_exists(ScoreTableController) instance_create(0,0,ScoreTableController);
|
||||||
|
instance_create(0,0,WinBanner);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CHANGE_MAP:
|
||||||
|
roomchange=true;
|
||||||
|
global.mapchanging = false;
|
||||||
|
global.currentMap = receivestring(global.serverSocket, 1);
|
||||||
|
global.currentMapMD5 = receivestring(global.serverSocket, 1);
|
||||||
|
if(global.currentMapMD5 == "") { // if this is an internal map (signified by the lack of an md5)
|
||||||
|
if(findInternalMapRoom(global.currentMap))
|
||||||
|
room_goto_fix(findInternalMapRoom(global.currentMap));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
show_message("Error:#Server went to invalid internal map: " + global.currentMap + "#Exiting.");
|
||||||
|
instance_destroy();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
} else { // it's an external map
|
||||||
|
if(string_pos("/", global.currentMap) != 0 or string_pos("\", global.currentMap) != 0)
|
||||||
|
{
|
||||||
|
show_message("Server sent illegal map name: "+global.currentMap);
|
||||||
|
instance_destroy();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
if(!file_exists("Maps/" + global.currentMap + ".png") or CustomMapGetMapMD5(global.currentMap) != global.currentMapMD5)
|
||||||
|
{ // Reconnect to the server to download the map
|
||||||
|
var oldReturnRoom;
|
||||||
|
oldReturnRoom = returnRoom;
|
||||||
|
returnRoom = DownloadRoom;
|
||||||
|
if (global.serverPluginsInUse)
|
||||||
|
noUnloadPlugins = true;
|
||||||
|
event_perform(ev_destroy,0);
|
||||||
|
ClientCreate();
|
||||||
|
if (global.serverPluginsInUse)
|
||||||
|
noReloadPlugins = true;
|
||||||
|
returnRoom = oldReturnRoom;
|
||||||
|
usePreviousPwd = true;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
room_goto_fix(CustomMapRoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i<ds_list_size(global.players); i+=1) {
|
||||||
|
player = ds_list_find_value(global.players, i);
|
||||||
|
if global.currentMapArea == 1 {
|
||||||
|
player.stats[KILLS] = 0;
|
||||||
|
player.stats[DEATHS] = 0;
|
||||||
|
player.stats[CAPS] = 0;
|
||||||
|
player.stats[ASSISTS] = 0;
|
||||||
|
player.stats[DESTRUCTION] = 0;
|
||||||
|
player.stats[STABS] = 0;
|
||||||
|
player.stats[HEALING] = 0;
|
||||||
|
player.stats[DEFENSES] = 0;
|
||||||
|
player.stats[INVULNS] = 0;
|
||||||
|
player.stats[BONUS] = 0;
|
||||||
|
player.stats[DOMINATIONS] = 0;
|
||||||
|
player.stats[REVENGE] = 0;
|
||||||
|
player.stats[POINTS] = 0;
|
||||||
|
player.roundStats[KILLS] = 0;
|
||||||
|
player.roundStats[DEATHS] = 0;
|
||||||
|
player.roundStats[CAPS] = 0;
|
||||||
|
player.roundStats[ASSISTS] = 0;
|
||||||
|
player.roundStats[DESTRUCTION] = 0;
|
||||||
|
player.roundStats[STABS] = 0;
|
||||||
|
player.roundStats[HEALING] = 0;
|
||||||
|
player.roundStats[DEFENSES] = 0;
|
||||||
|
player.roundStats[INVULNS] = 0;
|
||||||
|
player.roundStats[BONUS] = 0;
|
||||||
|
player.roundStats[DOMINATIONS] = 0;
|
||||||
|
player.roundStats[REVENGE] = 0;
|
||||||
|
player.roundStats[POINTS] = 0;
|
||||||
|
player.team = TEAM_SPECTATOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SERVER_FULL:
|
||||||
|
show_message("The server is full.");
|
||||||
|
instance_destroy();
|
||||||
|
exit;
|
||||||
|
|
||||||
|
case REWARD_CHALLENGE_CODE:
|
||||||
|
var challengeData;
|
||||||
|
receiveCompleteMessage(global.serverSocket,16,global.tempBuffer);
|
||||||
|
challengeData = read_binstring(global.tempBuffer, buffer_size(global.tempBuffer));
|
||||||
|
challengeData += socket_remote_ip(global.serverSocket);
|
||||||
|
|
||||||
|
write_ubyte(global.serverSocket, REWARD_CHALLENGE_RESPONSE);
|
||||||
|
write_binstring(global.serverSocket, hmac_md5_bin(global.rewardKey, challengeData));
|
||||||
|
socket_send(global.serverSocket);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REWARD_UPDATE:
|
||||||
|
receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
var rewardString;
|
||||||
|
rewardString = receivestring(global.serverSocket, 2);
|
||||||
|
doEventUpdateRewards(player, rewardString);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MESSAGE_STRING:
|
||||||
|
var message, notice;
|
||||||
|
message = receivestring(global.serverSocket, 1);
|
||||||
|
with NoticeO instance_destroy();
|
||||||
|
notice = instance_create(0, 0, NoticeO);
|
||||||
|
notice.notice = NOTICE_CUSTOM;
|
||||||
|
notice.message = message;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SENTRY_POSITION:
|
||||||
|
receiveCompleteMessage(global.serverSocket,5,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
if(player.sentry)
|
||||||
|
{
|
||||||
|
player.sentry.x = read_ushort(global.tempBuffer) / 5;
|
||||||
|
player.sentry.y = read_ushort(global.tempBuffer) / 5;
|
||||||
|
player.sentry.xprevious = player.sentry.x;
|
||||||
|
player.sentry.yprevious = player.sentry.y;
|
||||||
|
player.sentry.vspeed = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WEAPON_FIRE:
|
||||||
|
receiveCompleteMessage(global.serverSocket,9,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
|
||||||
|
if(player.object)
|
||||||
|
{
|
||||||
|
with(player.object)
|
||||||
|
{
|
||||||
|
x = read_ushort(global.tempBuffer)/5;
|
||||||
|
y = read_ushort(global.tempBuffer)/5;
|
||||||
|
hspeed = read_byte(global.tempBuffer)/8.5;
|
||||||
|
vspeed = read_byte(global.tempBuffer)/8.5;
|
||||||
|
xprevious = x;
|
||||||
|
yprevious = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
doEventFireWeapon(player, read_ushort(global.tempBuffer));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLUGIN_PACKET:
|
||||||
|
var packetID, packetLen, buf, success;
|
||||||
|
|
||||||
|
// fetch full packet
|
||||||
|
receiveCompleteMessage(global.serverSocket, 2, global.tempBuffer);
|
||||||
|
packetLen = read_ushort(global.tempBuffer);
|
||||||
|
receiveCompleteMessage(global.serverSocket, packetLen, global.tempBuffer);
|
||||||
|
|
||||||
|
packetID = read_ubyte(global.tempBuffer);
|
||||||
|
|
||||||
|
// get packet data
|
||||||
|
buf = buffer_create();
|
||||||
|
write_buffer_part(buf, global.tempBuffer, packetLen - 1);
|
||||||
|
|
||||||
|
// try to enqueue
|
||||||
|
// give "noone" value for client since received from server
|
||||||
|
success = _PluginPacketPush(packetID, buf, noone);
|
||||||
|
|
||||||
|
// if it returned false, packetID was invalid
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
// clear up buffer
|
||||||
|
buffer_destroy(buf);
|
||||||
|
show_error("ERROR when reading plugin packet: no such plugin packet ID " + string(packetID), true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLIENT_SETTINGS:
|
||||||
|
receiveCompleteMessage(global.serverSocket,2,global.tempBuffer);
|
||||||
|
player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
|
||||||
|
player.queueJump = read_ubyte(global.tempBuffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
promptRestartOrQuit("The Server sent unexpected data.");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} until(roomchange);
|
||||||
141
samples/Game Maker Language/Create.gml
Normal file
141
samples/Game Maker Language/Create.gml
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
Originally from /Source/gg2/Objects/Updater.events/Create.xml in Gang Garrison 2
|
||||||
|
|
||||||
|
Copyright (C) 2008-2013 Faucet Software
|
||||||
|
http://www.ganggarrison.com
|
||||||
|
|
||||||
|
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>.
|
||||||
|
|
||||||
|
Additional permission under GNU GPL version 3 section 7
|
||||||
|
If you modify this Program, or any covered work, by linking or combining it with the Game Maker runtime library,
|
||||||
|
the 39dll library/extension, Hobbel's Download Manager DLL, or modified versions of these libraries,
|
||||||
|
the licensors of this Program grant you additional permission to convey the resulting work.
|
||||||
|
*/
|
||||||
|
// Downloading code.
|
||||||
|
|
||||||
|
var downloadHandle, url, tmpfile, window_oldshowborder, window_oldfullscreen;
|
||||||
|
timeLeft = 0;
|
||||||
|
counter = 0;
|
||||||
|
AudioControlPlaySong(-1, false);
|
||||||
|
window_oldshowborder = window_get_showborder();
|
||||||
|
window_oldfullscreen = window_get_fullscreen();
|
||||||
|
window_set_fullscreen(false);
|
||||||
|
window_set_showborder(false);
|
||||||
|
|
||||||
|
if(global.updaterBetaChannel)
|
||||||
|
url = UPDATE_SOURCE_BETA;
|
||||||
|
else
|
||||||
|
url = UPDATE_SOURCE;
|
||||||
|
|
||||||
|
tmpfile = temp_directory + "\gg2update.zip";
|
||||||
|
|
||||||
|
downloadHandle = httpGet(url, -1);
|
||||||
|
|
||||||
|
while(!httpRequestStatus(downloadHandle))
|
||||||
|
{ // while download isn't finished
|
||||||
|
sleep(floor(1000/30)); // sleep for the equivalent of one frame
|
||||||
|
io_handle(); // this prevents GameMaker from appearing locked-up
|
||||||
|
httpRequestStep(downloadHandle);
|
||||||
|
|
||||||
|
// check if the user cancelled the download with the esc key
|
||||||
|
if(keyboard_check(vk_escape))
|
||||||
|
{
|
||||||
|
httpRequestDestroy(downloadHandle);
|
||||||
|
window_set_showborder(window_oldshowborder);
|
||||||
|
window_set_fullscreen(window_oldfullscreen);
|
||||||
|
room_goto_fix(Menu);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(counter == 0 || counter mod 60 == 0)
|
||||||
|
timer = random(359)+1;
|
||||||
|
draw_sprite(UpdaterBackgroundS,0,0,0);
|
||||||
|
draw_set_color(c_white);
|
||||||
|
draw_set_halign(fa_left);
|
||||||
|
draw_set_valign(fa_center);
|
||||||
|
minutes=floor(timer/60);
|
||||||
|
seconds=floor(timer-minutes*60);
|
||||||
|
draw_text(x,y-20,string(minutes) + " minutes " + string(seconds) + " seconds Remaining...");
|
||||||
|
counter+=1;
|
||||||
|
var progress, size;
|
||||||
|
progress = httpRequestResponseBodyProgress(downloadHandle);
|
||||||
|
size = httpRequestResponseBodySize(downloadHandle);
|
||||||
|
if (size != -1)
|
||||||
|
{
|
||||||
|
progressBar = floor((progress/size) * 20);
|
||||||
|
offset = 3;
|
||||||
|
for(i=0;i<progressBar;i+=1){
|
||||||
|
draw_sprite(UpdaterProgressS,0,x+offset,y);
|
||||||
|
offset+=12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
screen_refresh();
|
||||||
|
}
|
||||||
|
// Errored
|
||||||
|
if (httpRequestStatus(downloadHandle) == 2)
|
||||||
|
{
|
||||||
|
show_message("Downloading update failed!#" + httpRequestError(downloadHandle));
|
||||||
|
httpRequestDestroy(downloadHandle);
|
||||||
|
window_set_showborder(window_oldshowborder);
|
||||||
|
window_set_fullscreen(window_oldfullscreen);
|
||||||
|
room_goto_fix(Menu);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
// Request failed
|
||||||
|
if (httpRequestStatusCode(downloadHandle) != 200)
|
||||||
|
{
|
||||||
|
show_message("Downloading update failed!#" + string(httpRequestStatusCode(downloadHandle)) + " " + httpRequestReasonPhrase(downloadHandle));
|
||||||
|
httpRequestDestroy(downloadHandle);
|
||||||
|
window_set_showborder(window_oldshowborder);
|
||||||
|
window_set_fullscreen(window_oldfullscreen);
|
||||||
|
room_goto_fix(Menu);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_buffer_to_file(httpRequestResponseBody(downloadHandle), tmpfile);
|
||||||
|
httpRequestDestroy(downloadHandle);
|
||||||
|
|
||||||
|
if(!file_exists(tmpfile))
|
||||||
|
{
|
||||||
|
window_set_showborder(window_oldshowborder);
|
||||||
|
window_set_fullscreen(window_oldfullscreen);
|
||||||
|
show_message("Error updating: Missing gg2update.zip in temp directory, download failed(?)");
|
||||||
|
room_goto_fix(Menu);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rename existing "Gang Garrison 2.exe" to avoid conflict when extracting
|
||||||
|
if (file_exists("Gang Garrison 2.exe"))
|
||||||
|
{
|
||||||
|
var newName, n;
|
||||||
|
n = 1;
|
||||||
|
|
||||||
|
// increment until unused name found
|
||||||
|
do
|
||||||
|
{
|
||||||
|
newName = "gg2-old.delete.me." + string(n);
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
until(!file_exists(newName));
|
||||||
|
|
||||||
|
file_rename("Gang Garrison 2.exe", newName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// let's extract the downloaded file now.
|
||||||
|
extractzip(tmpfile, working_directory);
|
||||||
|
|
||||||
|
// run new version
|
||||||
|
execute_program("Gang Garrison 2.exe", "", false);
|
||||||
|
|
||||||
|
// exit
|
||||||
|
game_end();
|
||||||
161
samples/Game Maker Language/Draw.gml
Normal file
161
samples/Game Maker Language/Draw.gml
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
Originally from /Source/gg2/Objects/InGameElements/Character.events/Draw.xml in Gang Garrison 2
|
||||||
|
|
||||||
|
Copyright (C) 2008-2013 Faucet Software
|
||||||
|
http://www.ganggarrison.com
|
||||||
|
|
||||||
|
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>.
|
||||||
|
|
||||||
|
Additional permission under GNU GPL version 3 section 7
|
||||||
|
If you modify this Program, or any covered work, by linking or combining it with the Game Maker runtime library,
|
||||||
|
the 39dll library/extension, Hobbel's Download Manager DLL, or modified versions of these libraries,
|
||||||
|
the licensors of this Program grant you additional permission to convey the resulting work.
|
||||||
|
*/
|
||||||
|
|
||||||
|
xoffset = view_xview[0];
|
||||||
|
yoffset = view_yview[0];
|
||||||
|
xsize = view_wview[0];
|
||||||
|
ysize = view_hview[0];
|
||||||
|
|
||||||
|
if (distance_to_point(xoffset+xsize/2,yoffset+ysize/2) > 800)
|
||||||
|
exit;
|
||||||
|
|
||||||
|
var xr, yr;
|
||||||
|
xr = round(x);
|
||||||
|
yr = round(y);
|
||||||
|
|
||||||
|
image_alpha = cloakAlpha;
|
||||||
|
|
||||||
|
if (global.myself.team == team and canCloak)
|
||||||
|
image_alpha = cloakAlpha/2 + 0.5;
|
||||||
|
|
||||||
|
if (invisible)
|
||||||
|
exit;
|
||||||
|
|
||||||
|
if(stabbing)
|
||||||
|
image_alpha -= power(currentWeapon.stab.alpha, 2);
|
||||||
|
|
||||||
|
if team == global.myself.team && (player != global.myself || global.showHealthBar == 1){
|
||||||
|
draw_set_alpha(1);
|
||||||
|
draw_healthbar(xr-10, yr-30, xr+10, yr-25,hp*100/maxHp,c_black,c_red,c_green,0,true,true);
|
||||||
|
}
|
||||||
|
if(distance_to_point(mouse_x, mouse_y)<25) {
|
||||||
|
if cloak && team!=global.myself.team exit;
|
||||||
|
draw_set_alpha(1);
|
||||||
|
draw_set_halign(fa_center);
|
||||||
|
draw_set_valign(fa_bottom);
|
||||||
|
if(team==TEAM_RED) {
|
||||||
|
draw_set_color(c_red);
|
||||||
|
} else {
|
||||||
|
draw_set_color(c_blue);
|
||||||
|
}
|
||||||
|
draw_text(xr, yr-35, player.name);
|
||||||
|
|
||||||
|
if(team == global.myself.team && global.showTeammateStats)
|
||||||
|
{
|
||||||
|
if(weapons[0] == Medigun)
|
||||||
|
draw_text(xr,yr+50, "Superburst: " + string(currentWeapon.uberCharge/20) + "%");
|
||||||
|
else if(weapons[0] == Shotgun)
|
||||||
|
draw_text(xr,yr+50, "Nuts 'N' Bolts: " + string(nutsNBolts));
|
||||||
|
else if(weapons[0] == Minegun)
|
||||||
|
draw_text(xr,yr+50, "Lobbed Mines: " + string(currentWeapon.lobbed));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_set_alpha(1);
|
||||||
|
if team == TEAM_RED ubercolour = c_red;
|
||||||
|
if team == TEAM_BLUE ubercolour = c_blue;
|
||||||
|
|
||||||
|
var sprite, overlaySprite;
|
||||||
|
if zoomed
|
||||||
|
{
|
||||||
|
if (team == TEAM_RED)
|
||||||
|
sprite = SniperCrouchRedS;
|
||||||
|
else
|
||||||
|
sprite = SniperCrouchBlueS;
|
||||||
|
overlaySprite = sniperCrouchOverlay;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprite = sprite_index;
|
||||||
|
overlaySprite = overlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (omnomnomnom)
|
||||||
|
{
|
||||||
|
draw_sprite_ext_overlay(omnomnomnomSprite,omnomnomnomOverlay,omnomnomnomindex,xr,yr,image_xscale,image_yscale,image_angle,c_white,1);
|
||||||
|
if (ubered)
|
||||||
|
draw_sprite_ext_overlay(omnomnomnomSprite,omnomnomnomOverlay,omnomnomnomindex,xr,yr,image_xscale,image_yscale,image_angle,ubercolour,0.7);
|
||||||
|
}
|
||||||
|
else if (taunting)
|
||||||
|
{
|
||||||
|
draw_sprite_ext_overlay(tauntsprite,tauntOverlay,tauntindex,xr,yr,image_xscale,image_yscale,image_angle,c_white,1);
|
||||||
|
if (ubered)
|
||||||
|
draw_sprite_ext_overlay(tauntsprite,tauntOverlay,tauntindex,xr,yr,image_xscale,image_yscale,image_angle,ubercolour,0.7);
|
||||||
|
}
|
||||||
|
else if (player.humiliated)
|
||||||
|
draw_sprite_ext(humiliationPoses,floor(animationImage)+humiliationOffset,xr,yr,image_xscale,image_yscale,image_angle,c_white,image_alpha);
|
||||||
|
else if (!taunting)
|
||||||
|
{
|
||||||
|
if (cloak)
|
||||||
|
{
|
||||||
|
if (!ubered)
|
||||||
|
draw_sprite_ext(sprite,floor(animationImage+animationOffset),xr,yr,image_xscale,image_yscale,image_angle,c_white,image_alpha);
|
||||||
|
else if (ubered)
|
||||||
|
{
|
||||||
|
draw_sprite_ext(sprite,floor(animationImage+animationOffset),xr,yr,image_xscale,image_yscale,image_angle,c_white,1);
|
||||||
|
draw_sprite_ext(sprite,floor(animationImage+animationOffset),xr,yr,image_xscale,image_yscale,image_angle,ubercolour,0.7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!ubered)
|
||||||
|
draw_sprite_ext_overlay(sprite,overlaySprite,floor(animationImage+animationOffset),xr,yr,image_xscale,image_yscale,image_angle,c_white,image_alpha);
|
||||||
|
else if (ubered)
|
||||||
|
{
|
||||||
|
draw_sprite_ext_overlay(sprite,overlaySprite,floor(animationImage+animationOffset),xr,yr,image_xscale,image_yscale,image_angle,c_white,1);
|
||||||
|
draw_sprite_ext_overlay(sprite,overlaySprite,floor(animationImage+animationOffset),xr,yr,image_xscale,image_yscale,image_angle,ubercolour,0.7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (burnDuration > 0 or burnIntensity > 0) {
|
||||||
|
for(i = 0; i < numFlames * burnIntensity / maxIntensity; i += 1)
|
||||||
|
{
|
||||||
|
draw_sprite_ext(FlameS, alarm[5] + i + random(2), x + flameArray_x[i], y + flameArray_y[i], 1, 1, 0, c_white, burnDuration / maxDuration * 0.71 + 0.35);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copied from Lorgan's itemserver "angels" with slight modifications
|
||||||
|
// All credit be upon him
|
||||||
|
if (demon != -1)
|
||||||
|
{
|
||||||
|
demonX = median(x-40,demonX,x+40);
|
||||||
|
demonY = median(y-40,demonY,y);
|
||||||
|
demonOffset += demonDir;
|
||||||
|
if (abs(demonOffset) > 15)
|
||||||
|
demonDir *= -1;
|
||||||
|
|
||||||
|
var dir;
|
||||||
|
if (demonX > x)
|
||||||
|
dir = -1;
|
||||||
|
else
|
||||||
|
dir = 1;
|
||||||
|
|
||||||
|
if (demonFrame > sprite_get_number(demon))
|
||||||
|
demonFrame = 0;
|
||||||
|
|
||||||
|
if (stabbing || ubered)
|
||||||
|
draw_sprite_ext(demon,demonFrame+floor(animationImage)+7*player.team,demonX,demonY+demonOffset,dir*1,1,0,c_white,1);
|
||||||
|
else
|
||||||
|
draw_sprite_ext(demon,demonFrame+floor(animationImage)+7*player.team,demonX,demonY+demonOffset,dir*1,1,0,c_white,image_alpha);
|
||||||
|
|
||||||
|
demonFrame += 1;
|
||||||
|
}
|
||||||
251
samples/Game Maker Language/doEventPlayerDeath.gml
Normal file
251
samples/Game Maker Language/doEventPlayerDeath.gml
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
/*
|
||||||
|
Originally from /Source/gg2/Scripts/Events/doEventPlayerDeath.gml in Gang Garrison 2
|
||||||
|
|
||||||
|
Copyright (C) 2008-2013 Faucet Software
|
||||||
|
http://www.ganggarrison.com
|
||||||
|
|
||||||
|
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>.
|
||||||
|
|
||||||
|
Additional permission under GNU GPL version 3 section 7
|
||||||
|
If you modify this Program, or any covered work, by linking or combining it with the Game Maker runtime library,
|
||||||
|
the 39dll library/extension, Hobbel's Download Manager DLL, or modified versions of these libraries,
|
||||||
|
the licensors of this Program grant you additional permission to convey the resulting work.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform the "player death" event, i.e. change the appropriate scores,
|
||||||
|
* destroy the character object to much splattering and so on.
|
||||||
|
*
|
||||||
|
* argument0: The player whose character died
|
||||||
|
* argument1: The player who inflicted the fatal damage (or noone for unknown)
|
||||||
|
* argument2: The player who assisted the kill (or noone for no assist)
|
||||||
|
* argument3: The source of the fatal damage
|
||||||
|
*/
|
||||||
|
var victim, killer, assistant, damageSource;
|
||||||
|
victim = argument0;
|
||||||
|
killer = argument1;
|
||||||
|
assistant = argument2;
|
||||||
|
damageSource = argument3;
|
||||||
|
|
||||||
|
if(!instance_exists(killer))
|
||||||
|
killer = noone;
|
||||||
|
|
||||||
|
if(!instance_exists(assistant))
|
||||||
|
assistant = noone;
|
||||||
|
|
||||||
|
//*************************************
|
||||||
|
//* Scoring and Kill log
|
||||||
|
//*************************************
|
||||||
|
|
||||||
|
|
||||||
|
recordKillInLog(victim, killer, assistant, damageSource);
|
||||||
|
|
||||||
|
victim.stats[DEATHS] += 1;
|
||||||
|
if(killer)
|
||||||
|
{
|
||||||
|
if(damageSource == WEAPON_KNIFE || damageSource == WEAPON_BACKSTAB)
|
||||||
|
{
|
||||||
|
killer.stats[STABS] += 1;
|
||||||
|
killer.roundStats[STABS] += 1;
|
||||||
|
killer.stats[POINTS] += 1;
|
||||||
|
killer.roundStats[POINTS] +=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (victim.object.currentWeapon.object_index == Medigun)
|
||||||
|
{
|
||||||
|
if (victim.object.currentWeapon.uberReady)
|
||||||
|
{
|
||||||
|
killer.stats[BONUS] += 1;
|
||||||
|
killer.roundStats[BONUS] += 1;
|
||||||
|
killer.stats[POINTS] += 1;
|
||||||
|
killer.roundStats[POINTS] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (killer != victim)
|
||||||
|
{
|
||||||
|
killer.stats[KILLS] += 1;
|
||||||
|
killer.roundStats[KILLS] += 1;
|
||||||
|
killer.stats[POINTS] += 1;
|
||||||
|
killer.roundStats[POINTS] += 1;
|
||||||
|
if(victim.object.intel)
|
||||||
|
{
|
||||||
|
killer.stats[DEFENSES] += 1;
|
||||||
|
killer.roundStats[DEFENSES] += 1;
|
||||||
|
killer.stats[POINTS] += 1;
|
||||||
|
killer.roundStats[POINTS] += 1;
|
||||||
|
recordEventInLog(4, killer.team, killer.name, global.myself == killer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assistant)
|
||||||
|
{
|
||||||
|
assistant.stats[ASSISTS] += 1;
|
||||||
|
assistant.roundStats[ASSISTS] += 1;
|
||||||
|
assistant.stats[POINTS] += .5;
|
||||||
|
assistant.roundStats[POINTS] += .5;
|
||||||
|
}
|
||||||
|
|
||||||
|
//SPEC
|
||||||
|
if (victim == global.myself)
|
||||||
|
instance_create(victim.object.x, victim.object.y, Spectator);
|
||||||
|
|
||||||
|
//*************************************
|
||||||
|
//* Gibbing
|
||||||
|
//*************************************
|
||||||
|
var xoffset, yoffset, xsize, ysize;
|
||||||
|
|
||||||
|
xoffset = view_xview[0];
|
||||||
|
yoffset = view_yview[0];
|
||||||
|
xsize = view_wview[0];
|
||||||
|
ysize = view_hview[0];
|
||||||
|
|
||||||
|
randomize();
|
||||||
|
with(victim.object) {
|
||||||
|
if((damageSource == WEAPON_ROCKETLAUNCHER
|
||||||
|
or damageSource == WEAPON_MINEGUN or damageSource == FRAG_BOX
|
||||||
|
or damageSource == WEAPON_REFLECTED_STICKY or damageSource == WEAPON_REFLECTED_ROCKET
|
||||||
|
or damageSource == FINISHED_OFF_GIB or damageSource == GENERATOR_EXPLOSION)
|
||||||
|
and (player.class != CLASS_QUOTE) and (global.gibLevel>1)
|
||||||
|
and distance_to_point(xoffset+xsize/2,yoffset+ysize/2) < 900) {
|
||||||
|
if (hasReward(victim, 'PumpkinGibs'))
|
||||||
|
{
|
||||||
|
repeat(global.gibLevel * 2) {
|
||||||
|
createGib(x,y,PumpkinGib,hspeed,vspeed,random(145)-72, choose(0,1,1,2,2,3), false, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
repeat(global.gibLevel) {
|
||||||
|
createGib(x,y,Gib,hspeed,vspeed,random(145)-72, 0, false)
|
||||||
|
}
|
||||||
|
switch(player.team)
|
||||||
|
{
|
||||||
|
case TEAM_BLUE :
|
||||||
|
repeat(global.gibLevel - 1) {
|
||||||
|
createGib(x,y,BlueClump,hspeed,vspeed,random(145)-72, 0, false)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TEAM_RED :
|
||||||
|
repeat(global.gibLevel - 1) {
|
||||||
|
createGib(x,y,RedClump,hspeed,vspeed,random(145)-72, 0, false)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repeat(global.gibLevel * 14) {
|
||||||
|
var blood;
|
||||||
|
blood = instance_create(x+random(23)-11,y+random(23)-11,BloodDrop);
|
||||||
|
blood.hspeed=(random(21)-10);
|
||||||
|
blood.vspeed=(random(21)-13);
|
||||||
|
if (hasReward(victim, 'PumpkinGibs'))
|
||||||
|
{
|
||||||
|
blood.sprite_index = PumpkinJuiceS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasReward(victim, 'PumpkinGibs'))
|
||||||
|
{
|
||||||
|
//All Classes gib head, hands, and feet
|
||||||
|
if(global.gibLevel > 2 || choose(0,1) == 1)
|
||||||
|
createGib(x,y,Headgib,0,0,random(105)-52, player.class, false);
|
||||||
|
repeat(global.gibLevel -1){
|
||||||
|
//Medic has specially colored hands
|
||||||
|
if (player.class == CLASS_MEDIC){
|
||||||
|
if (player.team == TEAM_RED)
|
||||||
|
createGib(x,y,Hand, hspeed, vspeed, random(105)-52 , 9, false);
|
||||||
|
else
|
||||||
|
createGib(x,y,Hand, hspeed, vspeed, random(105)-52 , 10, false);
|
||||||
|
}else{
|
||||||
|
createGib(x,y,Hand, hspeed, vspeed, random(105)-52 , player.class, false);
|
||||||
|
}
|
||||||
|
createGib(x,y,Feet,random(5)-2,random(3),random(13)-6 , player.class, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Class specific gibs
|
||||||
|
switch(player.class) {
|
||||||
|
case CLASS_PYRO :
|
||||||
|
if(global.gibLevel > 2 || choose(0,1) == 1)
|
||||||
|
createGib(x,y,Accesory,hspeed,vspeed,random(105)-52, 4, false)
|
||||||
|
break;
|
||||||
|
case CLASS_SOLDIER :
|
||||||
|
if(global.gibLevel > 2 || choose(0,1) == 1){
|
||||||
|
switch(player.team) {
|
||||||
|
case TEAM_BLUE :
|
||||||
|
createGib(x,y,Accesory,hspeed,vspeed,random(105)-52, 2, false);
|
||||||
|
break;
|
||||||
|
case TEAM_RED :
|
||||||
|
createGib(x,y,Accesory,hspeed,vspeed,random(105)-52, 1, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CLASS_ENGINEER :
|
||||||
|
if(global.gibLevel > 2 || choose(0,1) == 1)
|
||||||
|
createGib(x,y,Accesory,hspeed,vspeed,random(105)-52, 3, false)
|
||||||
|
break;
|
||||||
|
case CLASS_SNIPER :
|
||||||
|
if(global.gibLevel > 2 || choose(0,1) == 1)
|
||||||
|
createGib(x,y,Accesory,hspeed,vspeed,random(105)-52, 0, false)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
playsound(x,y,Gibbing);
|
||||||
|
} else {
|
||||||
|
var deadbody;
|
||||||
|
if player.class != CLASS_QUOTE playsound(x,y,choose(DeathSnd1, DeathSnd2));
|
||||||
|
deadbody = instance_create(x,y-30,DeadGuy);
|
||||||
|
// 'GS' reward - *G*olden *S*tatue
|
||||||
|
if(hasReward(player, 'GS'))
|
||||||
|
{
|
||||||
|
deadbody.sprite_index = haxxyStatue;
|
||||||
|
deadbody.image_index = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
deadbody.sprite_index = sprite_index;
|
||||||
|
deadbody.image_index = CHARACTER_ANIMATION_DEAD;
|
||||||
|
}
|
||||||
|
deadbody.hspeed=hspeed;
|
||||||
|
deadbody.vspeed=vspeed;
|
||||||
|
if(hspeed>0) {
|
||||||
|
deadbody.image_xscale = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (global.gg_birthday){
|
||||||
|
myHat = instance_create(victim.object.x,victim.object.y,PartyHat);
|
||||||
|
myHat.image_index = victim.team;
|
||||||
|
}
|
||||||
|
if (global.xmas){
|
||||||
|
myHat = instance_create(victim.object.x,victim.object.y,XmasHat);
|
||||||
|
myHat.image_index = victim.team;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
with(victim.object) {
|
||||||
|
instance_destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************
|
||||||
|
//* Deathcam
|
||||||
|
//*************************************
|
||||||
|
if( global.killCam and victim == global.myself and killer and killer != victim and !(damageSource == KILL_BOX || damageSource == FRAG_BOX || damageSource == FINISHED_OFF || damageSource == FINISHED_OFF_GIB || damageSource == GENERATOR_EXPLOSION)) {
|
||||||
|
instance_create(0,0,DeathCam);
|
||||||
|
DeathCam.killedby=killer;
|
||||||
|
DeathCam.name=killer.name;
|
||||||
|
DeathCam.oldxview=view_xview[0];
|
||||||
|
DeathCam.oldyview=view_yview[0];
|
||||||
|
DeathCam.lastDamageSource=damageSource;
|
||||||
|
DeathCam.team = global.myself.team;
|
||||||
|
}
|
||||||
1469
samples/Game Maker Language/faucet-http.gml
Normal file
1469
samples/Game Maker Language/faucet-http.gml
Normal file
File diff suppressed because it is too large
Load Diff
484
samples/Game Maker Language/game_init.gml
Normal file
484
samples/Game Maker Language/game_init.gml
Normal file
@@ -0,0 +1,484 @@
|
|||||||
|
/*
|
||||||
|
Originally from /Source/gg2/Scripts/game_init.gml in Gang Garrison 2
|
||||||
|
|
||||||
|
Copyright (C) 2008-2013 Faucet Software
|
||||||
|
http://www.ganggarrison.com
|
||||||
|
|
||||||
|
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>.
|
||||||
|
|
||||||
|
Additional permission under GNU GPL version 3 section 7
|
||||||
|
If you modify this Program, or any covered work, by linking or combining it with the Game Maker runtime library,
|
||||||
|
the 39dll library/extension, Hobbel's Download Manager DLL, or modified versions of these libraries,
|
||||||
|
the licensors of this Program grant you additional permission to convey the resulting work.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Returns true if the game is successfully initialized, false if there was an error and we should quit.
|
||||||
|
{
|
||||||
|
instance_create(0,0,RoomChangeObserver);
|
||||||
|
set_little_endian_global(true);
|
||||||
|
if file_exists("game_errors.log") file_delete("game_errors.log");
|
||||||
|
if file_exists("last_plugin.log") file_delete("last_plugin.log");
|
||||||
|
|
||||||
|
// Delete old left-over files created by the updater
|
||||||
|
var backupFilename;
|
||||||
|
backupFilename = file_find_first("gg2-old.delete.me.*", 0);
|
||||||
|
while(backupFilename != "")
|
||||||
|
{
|
||||||
|
file_delete(backupFilename);
|
||||||
|
backupFilename = file_find_next();
|
||||||
|
}
|
||||||
|
file_find_close();
|
||||||
|
|
||||||
|
var customMapRotationFile, restart;
|
||||||
|
restart = false;
|
||||||
|
|
||||||
|
//import wav files for music
|
||||||
|
global.MenuMusic=sound_add(choose("Music/menumusic1.wav","Music/menumusic2.wav","Music/menumusic3.wav","Music/menumusic4.wav","Music/menumusic5.wav","Music/menumusic6.wav"), 1, true);
|
||||||
|
global.IngameMusic=sound_add("Music/ingamemusic.wav", 1, true);
|
||||||
|
global.FaucetMusic=sound_add("Music/faucetmusic.wav", 1, true);
|
||||||
|
if(global.MenuMusic != -1)
|
||||||
|
sound_volume(global.MenuMusic, 0.8);
|
||||||
|
if(global.IngameMusic != -1)
|
||||||
|
sound_volume(global.IngameMusic, 0.8);
|
||||||
|
if(global.FaucetMusic != -1)
|
||||||
|
sound_volume(global.FaucetMusic, 0.8);
|
||||||
|
|
||||||
|
global.sendBuffer = buffer_create();
|
||||||
|
global.tempBuffer = buffer_create();
|
||||||
|
global.HudCheck = false;
|
||||||
|
global.map_rotation = ds_list_create();
|
||||||
|
|
||||||
|
global.CustomMapCollisionSprite = -1;
|
||||||
|
|
||||||
|
window_set_region_scale(-1, false);
|
||||||
|
|
||||||
|
ini_open("gg2.ini");
|
||||||
|
global.playerName = ini_read_string("Settings", "PlayerName", "Player");
|
||||||
|
if string_count("#",global.playerName) > 0 global.playerName = "Player";
|
||||||
|
global.playerName = string_copy(global.playerName, 0, min(string_length(global.playerName), MAX_PLAYERNAME_LENGTH));
|
||||||
|
global.fullscreen = ini_read_real("Settings", "Fullscreen", 0);
|
||||||
|
global.useLobbyServer = ini_read_real("Settings", "UseLobby", 1);
|
||||||
|
global.hostingPort = ini_read_real("Settings", "HostingPort", 8190);
|
||||||
|
global.music = ini_read_real("Settings", "Music", ini_read_real("Settings", "IngameMusic", MUSIC_BOTH));
|
||||||
|
global.playerLimit = ini_read_real("Settings", "PlayerLimit", 10);
|
||||||
|
//thy playerlimit shalt not exceed 48!
|
||||||
|
if (global.playerLimit > 48)
|
||||||
|
{
|
||||||
|
if (global.dedicatedMode != 1)
|
||||||
|
show_message("Warning: Player Limit cannot exceed 48. It has been set to 48");
|
||||||
|
global.playerLimit = 48;
|
||||||
|
ini_write_real("Settings", "PlayerLimit", 48);
|
||||||
|
}
|
||||||
|
global.multiClientLimit = ini_read_real("Settings", "MultiClientLimit", 3);
|
||||||
|
global.particles = ini_read_real("Settings", "Particles", PARTICLES_NORMAL);
|
||||||
|
global.gibLevel = ini_read_real("Settings", "Gib Level", 3);
|
||||||
|
global.killCam = ini_read_real("Settings", "Kill Cam", 1);
|
||||||
|
global.monitorSync = ini_read_real("Settings", "Monitor Sync", 0);
|
||||||
|
if global.monitorSync == 1 set_synchronization(true);
|
||||||
|
else set_synchronization(false);
|
||||||
|
global.medicRadar = ini_read_real("Settings", "Healer Radar", 1);
|
||||||
|
global.showHealer = ini_read_real("Settings", "Show Healer", 1);
|
||||||
|
global.showHealing = ini_read_real("Settings", "Show Healing", 1);
|
||||||
|
global.showHealthBar = ini_read_real("Settings", "Show Healthbar", 0);
|
||||||
|
global.showTeammateStats = ini_read_real("Settings", "Show Extra Teammate Stats", 0);
|
||||||
|
global.serverPluginsPrompt = ini_read_real("Settings", "ServerPluginsPrompt", 1);
|
||||||
|
global.restartPrompt = ini_read_real("Settings", "RestartPrompt", 1);
|
||||||
|
//user HUD settings
|
||||||
|
global.timerPos=ini_read_real("Settings","Timer Position", 0)
|
||||||
|
global.killLogPos=ini_read_real("Settings","Kill Log Position", 0)
|
||||||
|
global.kothHudPos=ini_read_real("Settings","KoTH HUD Position", 0)
|
||||||
|
global.clientPassword = "";
|
||||||
|
// for admin menu
|
||||||
|
customMapRotationFile = ini_read_string("Server", "MapRotation", "");
|
||||||
|
global.shuffleRotation = ini_read_real("Server", "ShuffleRotation", 1);
|
||||||
|
global.timeLimitMins = max(1, min(255, ini_read_real("Server", "Time Limit", 15)));
|
||||||
|
global.serverPassword = ini_read_string("Server", "Password", "");
|
||||||
|
global.mapRotationFile = customMapRotationFile;
|
||||||
|
global.dedicatedMode = ini_read_real("Server", "Dedicated", 0);
|
||||||
|
global.serverName = ini_read_string("Server", "ServerName", "My Server");
|
||||||
|
global.welcomeMessage = ini_read_string("Server", "WelcomeMessage", "");
|
||||||
|
global.caplimit = max(1, min(255, ini_read_real("Server", "CapLimit", 5)));
|
||||||
|
global.caplimitBkup = global.caplimit;
|
||||||
|
global.autobalance = ini_read_real("Server", "AutoBalance",1);
|
||||||
|
global.Server_RespawntimeSec = ini_read_real("Server", "Respawn Time", 5);
|
||||||
|
global.rewardKey = unhex(ini_read_string("Haxxy", "RewardKey", ""));
|
||||||
|
global.rewardId = ini_read_string("Haxxy", "RewardId", "");
|
||||||
|
global.mapdownloadLimitBps = ini_read_real("Server", "Total bandwidth limit for map downloads in bytes per second", 50000);
|
||||||
|
global.updaterBetaChannel = ini_read_real("General", "UpdaterBetaChannel", isBetaVersion());
|
||||||
|
global.attemptPortForward = ini_read_real("Server", "Attempt UPnP Forwarding", 0);
|
||||||
|
global.serverPluginList = ini_read_string("Server", "ServerPluginList", "");
|
||||||
|
global.serverPluginsRequired = ini_read_real("Server", "ServerPluginsRequired", 0);
|
||||||
|
if (string_length(global.serverPluginList) > 254) {
|
||||||
|
show_message("Error: Server plugin list cannot exceed 254 characters");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var CrosshairFilename, CrosshairRemoveBG;
|
||||||
|
CrosshairFilename = ini_read_string("Settings", "CrosshairFilename", "");
|
||||||
|
CrosshairRemoveBG = ini_read_real("Settings", "CrosshairRemoveBG", 1);
|
||||||
|
global.queueJumping = ini_read_real("Settings", "Queued Jumping", 0);
|
||||||
|
|
||||||
|
global.backgroundHash = ini_read_string("Background", "BackgroundHash", "default");
|
||||||
|
global.backgroundTitle = ini_read_string("Background", "BackgroundTitle", "");
|
||||||
|
global.backgroundURL = ini_read_string("Background", "BackgroundURL", "");
|
||||||
|
global.backgroundShowVersion = ini_read_real("Background", "BackgroundShowVersion", true);
|
||||||
|
|
||||||
|
readClasslimitsFromIni();
|
||||||
|
|
||||||
|
global.currentMapArea=1;
|
||||||
|
global.totalMapAreas=1;
|
||||||
|
global.setupTimer=1800;
|
||||||
|
global.joinedServerName="";
|
||||||
|
global.serverPluginsInUse=false;
|
||||||
|
// Create plugin packet maps
|
||||||
|
global.pluginPacketBuffers = ds_map_create();
|
||||||
|
global.pluginPacketPlayers = ds_map_create();
|
||||||
|
|
||||||
|
ini_write_string("Settings", "PlayerName", global.playerName);
|
||||||
|
ini_write_real("Settings", "Fullscreen", global.fullscreen);
|
||||||
|
ini_write_real("Settings", "UseLobby", global.useLobbyServer);
|
||||||
|
ini_write_real("Settings", "HostingPort", global.hostingPort);
|
||||||
|
ini_key_delete("Settings", "IngameMusic");
|
||||||
|
ini_write_real("Settings", "Music", global.music);
|
||||||
|
ini_write_real("Settings", "PlayerLimit", global.playerLimit);
|
||||||
|
ini_write_real("Settings", "MultiClientLimit", global.multiClientLimit);
|
||||||
|
ini_write_real("Settings", "Particles", global.particles);
|
||||||
|
ini_write_real("Settings", "Gib Level", global.gibLevel);
|
||||||
|
ini_write_real("Settings", "Kill Cam", global.killCam);
|
||||||
|
ini_write_real("Settings", "Monitor Sync", global.monitorSync);
|
||||||
|
ini_write_real("Settings", "Healer Radar", global.medicRadar);
|
||||||
|
ini_write_real("Settings", "Show Healer", global.showHealer);
|
||||||
|
ini_write_real("Settings", "Show Healing", global.showHealing);
|
||||||
|
ini_write_real("Settings", "Show Healthbar", global.showHealthBar);
|
||||||
|
ini_write_real("Settings", "Show Extra Teammate Stats", global.showTeammateStats);
|
||||||
|
ini_write_real("Settings", "Timer Position", global.timerPos);
|
||||||
|
ini_write_real("Settings", "Kill Log Position", global.killLogPos);
|
||||||
|
ini_write_real("Settings", "KoTH HUD Position", global.kothHudPos);
|
||||||
|
ini_write_real("Settings", "ServerPluginsPrompt", global.serverPluginsPrompt);
|
||||||
|
ini_write_real("Settings", "RestartPrompt", global.restartPrompt);
|
||||||
|
ini_write_string("Server", "MapRotation", customMapRotationFile);
|
||||||
|
ini_write_real("Server", "ShuffleRotation", global.shuffleRotation);
|
||||||
|
ini_write_real("Server", "Dedicated", global.dedicatedMode);
|
||||||
|
ini_write_string("Server", "ServerName", global.serverName);
|
||||||
|
ini_write_string("Server", "WelcomeMessage", global.welcomeMessage);
|
||||||
|
ini_write_real("Server", "CapLimit", global.caplimit);
|
||||||
|
ini_write_real("Server", "AutoBalance", global.autobalance);
|
||||||
|
ini_write_real("Server", "Respawn Time", global.Server_RespawntimeSec);
|
||||||
|
ini_write_real("Server", "Total bandwidth limit for map downloads in bytes per second", global.mapdownloadLimitBps);
|
||||||
|
ini_write_real("Server", "Time Limit", global.timeLimitMins);
|
||||||
|
ini_write_string("Server", "Password", global.serverPassword);
|
||||||
|
ini_write_real("General", "UpdaterBetaChannel", global.updaterBetaChannel);
|
||||||
|
ini_write_real("Server", "Attempt UPnP Forwarding", global.attemptPortForward);
|
||||||
|
ini_write_string("Server", "ServerPluginList", global.serverPluginList);
|
||||||
|
ini_write_real("Server", "ServerPluginsRequired", global.serverPluginsRequired);
|
||||||
|
ini_write_string("Settings", "CrosshairFilename", CrosshairFilename);
|
||||||
|
ini_write_real("Settings", "CrosshairRemoveBG", CrosshairRemoveBG);
|
||||||
|
ini_write_real("Settings", "Queued Jumping", global.queueJumping);
|
||||||
|
|
||||||
|
ini_write_string("Background", "BackgroundHash", global.backgroundHash);
|
||||||
|
ini_write_string("Background", "BackgroundTitle", global.backgroundTitle);
|
||||||
|
ini_write_string("Background", "BackgroundURL", global.backgroundURL);
|
||||||
|
ini_write_real("Background", "BackgroundShowVersion", global.backgroundShowVersion);
|
||||||
|
|
||||||
|
ini_write_real("Classlimits", "Scout", global.classlimits[CLASS_SCOUT])
|
||||||
|
ini_write_real("Classlimits", "Pyro", global.classlimits[CLASS_PYRO])
|
||||||
|
ini_write_real("Classlimits", "Soldier", global.classlimits[CLASS_SOLDIER])
|
||||||
|
ini_write_real("Classlimits", "Heavy", global.classlimits[CLASS_HEAVY])
|
||||||
|
ini_write_real("Classlimits", "Demoman", global.classlimits[CLASS_DEMOMAN])
|
||||||
|
ini_write_real("Classlimits", "Medic", global.classlimits[CLASS_MEDIC])
|
||||||
|
ini_write_real("Classlimits", "Engineer", global.classlimits[CLASS_ENGINEER])
|
||||||
|
ini_write_real("Classlimits", "Spy", global.classlimits[CLASS_SPY])
|
||||||
|
ini_write_real("Classlimits", "Sniper", global.classlimits[CLASS_SNIPER])
|
||||||
|
ini_write_real("Classlimits", "Quote", global.classlimits[CLASS_QUOTE])
|
||||||
|
|
||||||
|
//screw the 0 index we will start with 1
|
||||||
|
//map_truefort
|
||||||
|
maps[1] = ini_read_real("Maps", "ctf_truefort", 1);
|
||||||
|
//map_2dfort
|
||||||
|
maps[2] = ini_read_real("Maps", "ctf_2dfort", 2);
|
||||||
|
//map_conflict
|
||||||
|
maps[3] = ini_read_real("Maps", "ctf_conflict", 3);
|
||||||
|
//map_classicwell
|
||||||
|
maps[4] = ini_read_real("Maps", "ctf_classicwell", 4);
|
||||||
|
//map_waterway
|
||||||
|
maps[5] = ini_read_real("Maps", "ctf_waterway", 5);
|
||||||
|
//map_orange
|
||||||
|
maps[6] = ini_read_real("Maps", "ctf_orange", 6);
|
||||||
|
//map_dirtbowl
|
||||||
|
maps[7] = ini_read_real("Maps", "cp_dirtbowl", 7);
|
||||||
|
//map_egypt
|
||||||
|
maps[8] = ini_read_real("Maps", "cp_egypt", 8);
|
||||||
|
//arena_montane
|
||||||
|
maps[9] = ini_read_real("Maps", "arena_montane", 9);
|
||||||
|
//arena_lumberyard
|
||||||
|
maps[10] = ini_read_real("Maps", "arena_lumberyard", 10);
|
||||||
|
//gen_destroy
|
||||||
|
maps[11] = ini_read_real("Maps", "gen_destroy", 11);
|
||||||
|
//koth_valley
|
||||||
|
maps[12] = ini_read_real("Maps", "koth_valley", 12);
|
||||||
|
//koth_corinth
|
||||||
|
maps[13] = ini_read_real("Maps", "koth_corinth", 13);
|
||||||
|
//koth_harvest
|
||||||
|
maps[14] = ini_read_real("Maps", "koth_harvest", 14);
|
||||||
|
//dkoth_atalia
|
||||||
|
maps[15] = ini_read_real("Maps", "dkoth_atalia", 15);
|
||||||
|
//dkoth_sixties
|
||||||
|
maps[16] = ini_read_real("Maps", "dkoth_sixties", 16);
|
||||||
|
|
||||||
|
//Server respawn time calculator. Converts each second to a frame. (read: multiply by 30 :hehe:)
|
||||||
|
if (global.Server_RespawntimeSec == 0)
|
||||||
|
{
|
||||||
|
global.Server_Respawntime = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
global.Server_Respawntime = global.Server_RespawntimeSec * 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
// I have to include this, or the client'll complain about an unknown variable.
|
||||||
|
global.mapchanging = false;
|
||||||
|
|
||||||
|
ini_write_real("Maps", "ctf_truefort", maps[1]);
|
||||||
|
ini_write_real("Maps", "ctf_2dfort", maps[2]);
|
||||||
|
ini_write_real("Maps", "ctf_conflict", maps[3]);
|
||||||
|
ini_write_real("Maps", "ctf_classicwell", maps[4]);
|
||||||
|
ini_write_real("Maps", "ctf_waterway", maps[5]);
|
||||||
|
ini_write_real("Maps", "ctf_orange", maps[6]);
|
||||||
|
ini_write_real("Maps", "cp_dirtbowl", maps[7]);
|
||||||
|
ini_write_real("Maps", "cp_egypt", maps[8]);
|
||||||
|
ini_write_real("Maps", "arena_montane", maps[9]);
|
||||||
|
ini_write_real("Maps", "arena_lumberyard", maps[10]);
|
||||||
|
ini_write_real("Maps", "gen_destroy", maps[11]);
|
||||||
|
ini_write_real("Maps", "koth_valley", maps[12]);
|
||||||
|
ini_write_real("Maps", "koth_corinth", maps[13]);
|
||||||
|
ini_write_real("Maps", "koth_harvest", maps[14]);
|
||||||
|
ini_write_real("Maps", "dkoth_atalia", maps[15]);
|
||||||
|
ini_write_real("Maps", "dkoth_sixties", maps[16]);
|
||||||
|
|
||||||
|
ini_close();
|
||||||
|
|
||||||
|
// parse the protocol version UUID for later use
|
||||||
|
global.protocolUuid = buffer_create();
|
||||||
|
parseUuid(PROTOCOL_UUID, global.protocolUuid);
|
||||||
|
|
||||||
|
global.gg2lobbyId = buffer_create();
|
||||||
|
parseUuid(GG2_LOBBY_UUID, global.gg2lobbyId);
|
||||||
|
|
||||||
|
// Create abbreviations array for rewards use
|
||||||
|
initRewards()
|
||||||
|
|
||||||
|
var a, IPRaw, portRaw;
|
||||||
|
doubleCheck=0;
|
||||||
|
global.launchMap = "";
|
||||||
|
|
||||||
|
for(a = 1; a <= parameter_count(); a += 1)
|
||||||
|
{
|
||||||
|
if (parameter_string(a) == "-dedicated")
|
||||||
|
{
|
||||||
|
global.dedicatedMode = 1;
|
||||||
|
}
|
||||||
|
else if (parameter_string(a) == "-restart")
|
||||||
|
{
|
||||||
|
restart = true;
|
||||||
|
}
|
||||||
|
else if (parameter_string(a) == "-server")
|
||||||
|
{
|
||||||
|
IPRaw = parameter_string(a+1);
|
||||||
|
if (doubleCheck == 1)
|
||||||
|
{
|
||||||
|
doubleCheck = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doubleCheck = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (parameter_string(a) == "-port")
|
||||||
|
{
|
||||||
|
portRaw = parameter_string(a+1);
|
||||||
|
if (doubleCheck == 1)
|
||||||
|
{
|
||||||
|
doubleCheck = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doubleCheck = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (parameter_string(a) == "-map")
|
||||||
|
{
|
||||||
|
global.launchMap = parameter_string(a+1);
|
||||||
|
global.dedicatedMode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doubleCheck == 2)
|
||||||
|
{
|
||||||
|
global.serverPort = real(portRaw);
|
||||||
|
global.serverIP = IPRaw;
|
||||||
|
global.isHost = false;
|
||||||
|
instance_create(0,0,Client);
|
||||||
|
}
|
||||||
|
|
||||||
|
global.customMapdesginated = 0;
|
||||||
|
|
||||||
|
// if the user defined a valid map rotation file, then load from there
|
||||||
|
|
||||||
|
if(customMapRotationFile != "" && file_exists(customMapRotationFile) && global.launchMap == "") {
|
||||||
|
global.customMapdesginated = 1;
|
||||||
|
var fileHandle, i, mapname;
|
||||||
|
fileHandle = file_text_open_read(customMapRotationFile);
|
||||||
|
for(i = 1; !file_text_eof(fileHandle); i += 1) {
|
||||||
|
mapname = file_text_read_string(fileHandle);
|
||||||
|
// remove leading whitespace from the string
|
||||||
|
while(string_char_at(mapname, 0) == " " || string_char_at(mapname, 0) == chr(9)) { // while it starts with a space or tab
|
||||||
|
mapname = string_delete(mapname, 0, 1); // delete that space or tab
|
||||||
|
}
|
||||||
|
if(mapname != "" && string_char_at(mapname, 0) != "#") { // if it's not blank and it's not a comment (starting with #)
|
||||||
|
ds_list_add(global.map_rotation, mapname);
|
||||||
|
}
|
||||||
|
file_text_readln(fileHandle);
|
||||||
|
}
|
||||||
|
file_text_close(fileHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (global.launchMap != "") && (global.dedicatedMode == 1)
|
||||||
|
{
|
||||||
|
ds_list_add(global.map_rotation, global.launchMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
else { // else load from the ini file Maps section
|
||||||
|
//Set up the map rotation stuff
|
||||||
|
var i, sort_list;
|
||||||
|
sort_list = ds_list_create();
|
||||||
|
for(i=1; i <= 16; i += 1) {
|
||||||
|
if(maps[i] != 0) ds_list_add(sort_list, ((100*maps[i])+i));
|
||||||
|
}
|
||||||
|
ds_list_sort(sort_list, 1);
|
||||||
|
|
||||||
|
// translate the numbers back into the names they represent
|
||||||
|
for(i=0; i < ds_list_size(sort_list); i += 1) {
|
||||||
|
switch(ds_list_find_value(sort_list, i) mod 100) {
|
||||||
|
case 1:
|
||||||
|
ds_list_add(global.map_rotation, "ctf_truefort");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ds_list_add(global.map_rotation, "ctf_2dfort");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ds_list_add(global.map_rotation, "ctf_conflict");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
ds_list_add(global.map_rotation, "ctf_classicwell");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
ds_list_add(global.map_rotation, "ctf_waterway");
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
ds_list_add(global.map_rotation, "ctf_orange");
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
ds_list_add(global.map_rotation, "cp_dirtbowl");
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
ds_list_add(global.map_rotation, "cp_egypt");
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
ds_list_add(global.map_rotation, "arena_montane");
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
ds_list_add(global.map_rotation, "arena_lumberyard");
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
ds_list_add(global.map_rotation, "gen_destroy");
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
ds_list_add(global.map_rotation, "koth_valley");
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
ds_list_add(global.map_rotation, "koth_corinth");
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
ds_list_add(global.map_rotation, "koth_harvest");
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
ds_list_add(global.map_rotation, "dkoth_atalia");
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
ds_list_add(global.map_rotation, "dkoth_sixties");
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ds_list_destroy(sort_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
window_set_fullscreen(global.fullscreen);
|
||||||
|
|
||||||
|
global.gg2Font = font_add_sprite(gg2FontS,ord("!"),false,0);
|
||||||
|
global.countFont = font_add_sprite(countFontS, ord("0"),false,2);
|
||||||
|
draw_set_font(global.gg2Font);
|
||||||
|
cursor_sprite = CrosshairS;
|
||||||
|
|
||||||
|
if(!directory_exists(working_directory + "\Maps")) directory_create(working_directory + "\Maps");
|
||||||
|
|
||||||
|
instance_create(0, 0, AudioControl);
|
||||||
|
instance_create(0, 0, SSControl);
|
||||||
|
|
||||||
|
// custom dialog box graphics
|
||||||
|
message_background(popupBackgroundB);
|
||||||
|
message_button(popupButtonS);
|
||||||
|
message_text_font("Century",9,c_white,1);
|
||||||
|
message_button_font("Century",9,c_white,1);
|
||||||
|
message_input_font("Century",9,c_white,0);
|
||||||
|
|
||||||
|
//Key Mapping
|
||||||
|
ini_open("controls.gg2");
|
||||||
|
global.jump = ini_read_real("Controls", "jump", ord("W"));
|
||||||
|
global.down = ini_read_real("Controls", "down", ord("S"));
|
||||||
|
global.left = ini_read_real("Controls", "left", ord("A"));
|
||||||
|
global.right = ini_read_real("Controls", "right", ord("D"));
|
||||||
|
global.attack = ini_read_real("Controls", "attack", MOUSE_LEFT);
|
||||||
|
global.special = ini_read_real("Controls", "special", MOUSE_RIGHT);
|
||||||
|
global.taunt = ini_read_real("Controls", "taunt", ord("F"));
|
||||||
|
global.chat1 = ini_read_real("Controls", "chat1", ord("Z"));
|
||||||
|
global.chat2 = ini_read_real("Controls", "chat2", ord("X"));
|
||||||
|
global.chat3 = ini_read_real("Controls", "chat3", ord("C"));
|
||||||
|
global.medic = ini_read_real("Controls", "medic", ord("E"));
|
||||||
|
global.drop = ini_read_real("Controls", "drop", ord("B"));
|
||||||
|
global.changeTeam = ini_read_real("Controls", "changeTeam", ord("N"));
|
||||||
|
global.changeClass = ini_read_real("Controls", "changeClass", ord("M"));
|
||||||
|
global.showScores = ini_read_real("Controls", "showScores", vk_shift);
|
||||||
|
ini_close();
|
||||||
|
|
||||||
|
calculateMonthAndDay();
|
||||||
|
|
||||||
|
if(!directory_exists(working_directory + "\Plugins")) directory_create(working_directory + "\Plugins");
|
||||||
|
loadplugins();
|
||||||
|
|
||||||
|
/* Windows 8 is known to crash GM when more than three (?) sounds play at once
|
||||||
|
* We'll store the kernel version (Win8 is 6.2, Win7 is 6.1) and check it there.
|
||||||
|
***/
|
||||||
|
registry_set_root(1); // HKLM
|
||||||
|
global.NTKernelVersion = real(registry_read_string_ext("\SOFTWARE\Microsoft\Windows NT\CurrentVersion\", "CurrentVersion")); // SIC
|
||||||
|
|
||||||
|
if (file_exists(CrosshairFilename))
|
||||||
|
{
|
||||||
|
sprite_replace(CrosshairS,CrosshairFilename,1,CrosshairRemoveBG,false,0,0);
|
||||||
|
sprite_set_offset(CrosshairS,sprite_get_width(CrosshairS)/2,sprite_get_height(CrosshairS)/2);
|
||||||
|
}
|
||||||
|
if(global.dedicatedMode == 1) {
|
||||||
|
AudioControlToggleMute();
|
||||||
|
room_goto_fix(Menu);
|
||||||
|
} else if(restart) {
|
||||||
|
room_goto_fix(Menu);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
252
samples/Game Maker Language/loadserverplugins.gml
Normal file
252
samples/Game Maker Language/loadserverplugins.gml
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
/*
|
||||||
|
Originally from /Source/gg2/Scripts/Plugins/loadserverplugins.gml in Gang Garrison 2
|
||||||
|
|
||||||
|
Copyright (C) 2008-2013 Faucet Software
|
||||||
|
http://www.ganggarrison.com
|
||||||
|
|
||||||
|
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>.
|
||||||
|
|
||||||
|
Additional permission under GNU GPL version 3 section 7
|
||||||
|
If you modify this Program, or any covered work, by linking or combining it with the Game Maker runtime library,
|
||||||
|
the 39dll library/extension, Hobbel's Download Manager DLL, or modified versions of these libraries,
|
||||||
|
the licensors of this Program grant you additional permission to convey the resulting work.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// loads plugins from ganggarrison.com asked for by server
|
||||||
|
// argument0 - comma separated plugin list (pluginname@md5hash)
|
||||||
|
// returns true on success, false on failure
|
||||||
|
var list, hashList, text, i, pluginname, pluginhash, realhash, url, handle, filesize, progress, tempfile, tempdir, failed, lastContact, isCached;
|
||||||
|
|
||||||
|
failed = false;
|
||||||
|
list = ds_list_create();
|
||||||
|
lastContact = 0;
|
||||||
|
isCached = false;
|
||||||
|
isDebug = false;
|
||||||
|
hashList = ds_list_create();
|
||||||
|
|
||||||
|
// split plugin list string
|
||||||
|
list = split(argument0, ',');
|
||||||
|
|
||||||
|
// Split hashes from plugin names
|
||||||
|
for (i = 0; i < ds_list_size(list); i += 1)
|
||||||
|
{
|
||||||
|
text = ds_list_find_value(list, i);
|
||||||
|
pluginname = string_copy(text, 0, string_pos("@", text) - 1);
|
||||||
|
pluginhash = string_copy(text, string_pos("@", text) + 1, string_length(text) - string_pos("@", text));
|
||||||
|
ds_list_replace(list, i, pluginname);
|
||||||
|
ds_list_add(hashList, pluginhash);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check plugin names and check for duplicates
|
||||||
|
for (i = 0; i < ds_list_size(list); i += 1)
|
||||||
|
{
|
||||||
|
pluginname = ds_list_find_value(list, i);
|
||||||
|
|
||||||
|
// invalid plugin name
|
||||||
|
if (!checkpluginname(pluginname))
|
||||||
|
{
|
||||||
|
show_message('Error loading server-sent plugins - invalid plugin name:#"' + pluginname + '"');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// is duplicate
|
||||||
|
else if (ds_list_find_index(list, pluginname) != i)
|
||||||
|
{
|
||||||
|
show_message('Error loading server-sent plugins - duplicate plugin:#"' + pluginname + '"');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Download plugins
|
||||||
|
for (i = 0; i < ds_list_size(list); i += 1)
|
||||||
|
{
|
||||||
|
pluginname = ds_list_find_value(list, i);
|
||||||
|
pluginhash = ds_list_find_value(hashList, i);
|
||||||
|
isDebug = file_exists(working_directory + "\ServerPluginsDebug\" + pluginname + ".zip");
|
||||||
|
isCached = file_exists(working_directory + "\ServerPluginsCache\" + pluginname + "@" + pluginhash);
|
||||||
|
tempfile = temp_directory + "\" + pluginname + ".zip.tmp";
|
||||||
|
tempdir = temp_directory + "\" + pluginname + ".tmp";
|
||||||
|
|
||||||
|
// check to see if we have a local copy for debugging
|
||||||
|
if (isDebug)
|
||||||
|
{
|
||||||
|
file_copy(working_directory + "\ServerPluginsDebug\" + pluginname + ".zip", tempfile);
|
||||||
|
// show warning
|
||||||
|
if (global.isHost)
|
||||||
|
{
|
||||||
|
show_message(
|
||||||
|
"Warning: server-sent plugin '"
|
||||||
|
+ pluginname
|
||||||
|
+ "' is being loaded from ServerPluginsDebug. Make sure clients have the same version, else they may be unable to connect."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
show_message(
|
||||||
|
"Warning: server-sent plugin '"
|
||||||
|
+ pluginname
|
||||||
|
+ "' is being loaded from ServerPluginsDebug. Make sure the server has the same version, else you may be unable to connect."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// otherwise, check if we have it cached
|
||||||
|
else if (isCached)
|
||||||
|
{
|
||||||
|
file_copy(working_directory + "\ServerPluginsCache\" + pluginname + "@" + pluginhash, tempfile);
|
||||||
|
}
|
||||||
|
// otherwise, download as usual
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// construct the URL
|
||||||
|
// http://www.ganggarrison.com/plugins/$PLUGINNAME$@$PLUGINHASH$.zip)
|
||||||
|
url = PLUGIN_SOURCE + pluginname + "@" + pluginhash + ".zip";
|
||||||
|
|
||||||
|
// let's make the download handle
|
||||||
|
handle = httpGet(url, -1);
|
||||||
|
|
||||||
|
// download it
|
||||||
|
while (!httpRequestStatus(handle)) {
|
||||||
|
// prevent game locking up
|
||||||
|
io_handle();
|
||||||
|
|
||||||
|
httpRequestStep(handle);
|
||||||
|
|
||||||
|
if (!global.isHost) {
|
||||||
|
// send ping if we haven't contacted server in 20 seconds
|
||||||
|
// we need to do this to keep the connection open
|
||||||
|
if (current_time-lastContact > 20000) {
|
||||||
|
write_byte(global.serverSocket, PING);
|
||||||
|
socket_send(global.serverSocket);
|
||||||
|
lastContact = current_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw progress bar since they may be waiting a while
|
||||||
|
filesize = httpRequestResponseBodySize(handle);
|
||||||
|
progress = httpRequestResponseBodyProgress(handle);
|
||||||
|
draw_background_ext(background_index[0], 0, 0, background_xscale[0], background_yscale[0], 0, c_white, 1);
|
||||||
|
draw_set_color(c_white);
|
||||||
|
draw_set_alpha(1);
|
||||||
|
draw_set_halign(fa_left);
|
||||||
|
draw_rectangle(50, 550, 300, 560, 2);
|
||||||
|
draw_text(50, 530, "Downloading server-sent plugin " + string(i + 1) + "/" + string(ds_list_size(list)) + ' - "' + pluginname + '"');
|
||||||
|
if (filesize != -1)
|
||||||
|
draw_rectangle(50, 550, 50 + progress / filesize * 250, 560, 0);
|
||||||
|
screen_refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
// errored
|
||||||
|
if (httpRequestStatus(handle) == 2)
|
||||||
|
{
|
||||||
|
show_message('Error loading server-sent plugins - download failed for "' + pluginname + '":#' + httpRequestError(handle));
|
||||||
|
failed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// request failed
|
||||||
|
if (httpRequestStatusCode(handle) != 200)
|
||||||
|
{
|
||||||
|
show_message('Error loading server-sent plugins - download failed for "' + pluginname + '":#' + string(httpRequestStatusCode(handle)) + ' ' + httpRequestReasonPhrase(handle));
|
||||||
|
failed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
write_buffer_to_file(httpRequestResponseBody(handle), tempfile);
|
||||||
|
if (!file_exists(tempfile))
|
||||||
|
{
|
||||||
|
show_message('Error loading server-sent plugins - download failed for "' + pluginname + '":# No such file?');
|
||||||
|
failed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
httpRequestDestroy(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check file integrity
|
||||||
|
realhash = GG2DLL_compute_MD5(tempfile);
|
||||||
|
if (realhash != pluginhash)
|
||||||
|
{
|
||||||
|
show_message('Error loading server-sent plugins - integrity check failed (MD5 hash mismatch) for:#"' + pluginname + '"');
|
||||||
|
failed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't try to cache debug plugins
|
||||||
|
if (!isDebug)
|
||||||
|
{
|
||||||
|
// add to cache if we don't already have it
|
||||||
|
if (!file_exists(working_directory + "\ServerPluginsCache\" + pluginname + "@" + pluginhash))
|
||||||
|
{
|
||||||
|
// make sure directory exists
|
||||||
|
if (!directory_exists(working_directory + "\ServerPluginsCache"))
|
||||||
|
{
|
||||||
|
directory_create(working_directory + "\ServerPluginsCache");
|
||||||
|
}
|
||||||
|
// store in cache
|
||||||
|
file_copy(tempfile, working_directory + "\ServerPluginsCache\" + pluginname + "@" + pluginhash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// let's get 7-zip to extract the files
|
||||||
|
extractzip(tempfile, tempdir);
|
||||||
|
|
||||||
|
// if the directory doesn't exist, extracting presumably failed
|
||||||
|
if (!directory_exists(tempdir))
|
||||||
|
{
|
||||||
|
show_message('Error loading server-sent plugins - extracting zip failed for:#"' + pluginname + '"');
|
||||||
|
failed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!failed)
|
||||||
|
{
|
||||||
|
// Execute plugins
|
||||||
|
for (i = 0; i < ds_list_size(list); i += 1)
|
||||||
|
{
|
||||||
|
pluginname = ds_list_find_value(list, i);
|
||||||
|
tempdir = temp_directory + "\" + pluginname + ".tmp";
|
||||||
|
|
||||||
|
// Debugging facility, so we know *which* plugin caused compile/execute error
|
||||||
|
fp = file_text_open_write(working_directory + "\last_plugin.log");
|
||||||
|
file_text_write_string(fp, pluginname);
|
||||||
|
file_text_close(fp);
|
||||||
|
|
||||||
|
// packetID is (i), so make queues for it
|
||||||
|
ds_map_add(global.pluginPacketBuffers, i, ds_queue_create());
|
||||||
|
ds_map_add(global.pluginPacketPlayers, i, ds_queue_create());
|
||||||
|
|
||||||
|
// Execute plugin
|
||||||
|
execute_file(
|
||||||
|
// the plugin's main gml file must be in the root of the zip
|
||||||
|
// it is called plugin.gml
|
||||||
|
tempdir + "\plugin.gml",
|
||||||
|
// the plugin needs to know where it is
|
||||||
|
// so the temporary directory is passed as first argument
|
||||||
|
tempdir,
|
||||||
|
// the plugin needs to know its packetID
|
||||||
|
// so it is passed as the second argument
|
||||||
|
i
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete last plugin log
|
||||||
|
file_delete(working_directory + "\last_plugin.log");
|
||||||
|
|
||||||
|
// Get rid of plugin list
|
||||||
|
ds_list_destroy(list);
|
||||||
|
|
||||||
|
// Get rid of plugin hash list
|
||||||
|
ds_list_destroy(hashList);
|
||||||
|
|
||||||
|
return !failed;
|
||||||
384
samples/Game Maker Language/processClientCommands.gml
Normal file
384
samples/Game Maker Language/processClientCommands.gml
Normal file
@@ -0,0 +1,384 @@
|
|||||||
|
/*
|
||||||
|
Originally from /Source/gg2/Scripts/GameServer/processClientCommands.gml in Gang Garrison 2
|
||||||
|
|
||||||
|
Copyright (C) 2008-2013 Faucet Software
|
||||||
|
http://www.ganggarrison.com
|
||||||
|
|
||||||
|
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>.
|
||||||
|
|
||||||
|
Additional permission under GNU GPL version 3 section 7
|
||||||
|
If you modify this Program, or any covered work, by linking or combining it with the Game Maker runtime library,
|
||||||
|
the 39dll library/extension, Hobbel's Download Manager DLL, or modified versions of these libraries,
|
||||||
|
the licensors of this Program grant you additional permission to convey the resulting work.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var player, playerId, commandLimitRemaining;
|
||||||
|
|
||||||
|
player = argument0;
|
||||||
|
playerId = argument1;
|
||||||
|
|
||||||
|
// To prevent players from flooding the server, limit the number of commands to process per step and player.
|
||||||
|
commandLimitRemaining = 10;
|
||||||
|
|
||||||
|
with(player) {
|
||||||
|
if(!variable_local_exists("commandReceiveState")) {
|
||||||
|
// 0: waiting for command byte.
|
||||||
|
// 1: waiting for command data length (1 byte)
|
||||||
|
// 2: waiting for command data.
|
||||||
|
commandReceiveState = 0;
|
||||||
|
commandReceiveExpectedBytes = 1;
|
||||||
|
commandReceiveCommand = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while(commandLimitRemaining > 0) {
|
||||||
|
var socket;
|
||||||
|
socket = player.socket;
|
||||||
|
if(!tcp_receive(socket, player.commandReceiveExpectedBytes)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(player.commandReceiveState)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
player.commandReceiveCommand = read_ubyte(socket);
|
||||||
|
switch(commandBytes[player.commandReceiveCommand]) {
|
||||||
|
case commandBytesInvalidCommand:
|
||||||
|
// Invalid byte received. Wait for another command byte.
|
||||||
|
break;
|
||||||
|
|
||||||
|
case commandBytesPrefixLength1:
|
||||||
|
player.commandReceiveState = 1;
|
||||||
|
player.commandReceiveExpectedBytes = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case commandBytesPrefixLength2:
|
||||||
|
player.commandReceiveState = 3;
|
||||||
|
player.commandReceiveExpectedBytes = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
player.commandReceiveState = 2;
|
||||||
|
player.commandReceiveExpectedBytes = commandBytes[player.commandReceiveCommand];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
player.commandReceiveState = 2;
|
||||||
|
player.commandReceiveExpectedBytes = read_ubyte(socket);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
player.commandReceiveState = 2;
|
||||||
|
player.commandReceiveExpectedBytes = read_ushort(socket);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
player.commandReceiveState = 0;
|
||||||
|
player.commandReceiveExpectedBytes = 1;
|
||||||
|
commandLimitRemaining -= 1;
|
||||||
|
|
||||||
|
switch(player.commandReceiveCommand)
|
||||||
|
{
|
||||||
|
case PLAYER_LEAVE:
|
||||||
|
socket_destroy(player.socket);
|
||||||
|
player.socket = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLAYER_CHANGECLASS:
|
||||||
|
var class;
|
||||||
|
class = read_ubyte(socket);
|
||||||
|
if(getCharacterObject(player.team, class) != -1)
|
||||||
|
{
|
||||||
|
if(player.object != -1)
|
||||||
|
{
|
||||||
|
with(player.object)
|
||||||
|
{
|
||||||
|
if (collision_point(x,y,SpawnRoom,0,0) < 0)
|
||||||
|
{
|
||||||
|
if (!instance_exists(lastDamageDealer) || lastDamageDealer == player)
|
||||||
|
{
|
||||||
|
sendEventPlayerDeath(player, player, noone, BID_FAREWELL);
|
||||||
|
doEventPlayerDeath(player, player, noone, BID_FAREWELL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var assistant;
|
||||||
|
assistant = secondToLastDamageDealer;
|
||||||
|
if (lastDamageDealer.object)
|
||||||
|
if (lastDamageDealer.object.healer)
|
||||||
|
assistant = lastDamageDealer.object.healer;
|
||||||
|
sendEventPlayerDeath(player, lastDamageDealer, assistant, FINISHED_OFF);
|
||||||
|
doEventPlayerDeath(player, lastDamageDealer, assistant, FINISHED_OFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
instance_destroy();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(player.alarm[5]<=0)
|
||||||
|
player.alarm[5] = 1;
|
||||||
|
class = checkClasslimits(player, player.team, class);
|
||||||
|
player.class = class;
|
||||||
|
ServerPlayerChangeclass(playerId, player.class, global.sendBuffer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLAYER_CHANGETEAM:
|
||||||
|
var newTeam, balance, redSuperiority;
|
||||||
|
newTeam = read_ubyte(socket);
|
||||||
|
|
||||||
|
redSuperiority = 0 //calculate which team is bigger
|
||||||
|
with(Player)
|
||||||
|
{
|
||||||
|
if(team == TEAM_RED)
|
||||||
|
redSuperiority += 1;
|
||||||
|
else if(team == TEAM_BLUE)
|
||||||
|
redSuperiority -= 1;
|
||||||
|
}
|
||||||
|
if(redSuperiority > 0)
|
||||||
|
balance = TEAM_RED;
|
||||||
|
else if(redSuperiority < 0)
|
||||||
|
balance = TEAM_BLUE;
|
||||||
|
else
|
||||||
|
balance = -1;
|
||||||
|
|
||||||
|
if(balance != newTeam)
|
||||||
|
{
|
||||||
|
if(getCharacterObject(newTeam, player.class) != -1 or newTeam==TEAM_SPECTATOR)
|
||||||
|
{
|
||||||
|
if(player.object != -1)
|
||||||
|
{
|
||||||
|
with(player.object)
|
||||||
|
{
|
||||||
|
if (!instance_exists(lastDamageDealer) || lastDamageDealer == player)
|
||||||
|
{
|
||||||
|
sendEventPlayerDeath(player, player, noone, BID_FAREWELL);
|
||||||
|
doEventPlayerDeath(player, player, noone, BID_FAREWELL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var assistant;
|
||||||
|
assistant = secondToLastDamageDealer;
|
||||||
|
if (lastDamageDealer.object)
|
||||||
|
if (lastDamageDealer.object.healer)
|
||||||
|
assistant = lastDamageDealer.object.healer;
|
||||||
|
sendEventPlayerDeath(player, lastDamageDealer, assistant, FINISHED_OFF);
|
||||||
|
doEventPlayerDeath(player, lastDamageDealer, assistant, FINISHED_OFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player.alarm[5] = global.Server_Respawntime;
|
||||||
|
}
|
||||||
|
else if(player.alarm[5]<=0)
|
||||||
|
player.alarm[5] = 1;
|
||||||
|
var newClass;
|
||||||
|
newClass = checkClasslimits(player, newTeam, player.class);
|
||||||
|
if newClass != player.class
|
||||||
|
{
|
||||||
|
player.class = newClass;
|
||||||
|
ServerPlayerChangeclass(playerId, player.class, global.sendBuffer);
|
||||||
|
}
|
||||||
|
player.team = newTeam;
|
||||||
|
ServerPlayerChangeteam(playerId, player.team, global.sendBuffer);
|
||||||
|
ServerBalanceTeams();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CHAT_BUBBLE:
|
||||||
|
var bubbleImage;
|
||||||
|
bubbleImage = read_ubyte(socket);
|
||||||
|
if(global.aFirst) {
|
||||||
|
bubbleImage = 0;
|
||||||
|
}
|
||||||
|
write_ubyte(global.sendBuffer, CHAT_BUBBLE);
|
||||||
|
write_ubyte(global.sendBuffer, playerId);
|
||||||
|
write_ubyte(global.sendBuffer, bubbleImage);
|
||||||
|
|
||||||
|
setChatBubble(player, bubbleImage);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BUILD_SENTRY:
|
||||||
|
if(player.object != -1)
|
||||||
|
{
|
||||||
|
if(player.class == CLASS_ENGINEER
|
||||||
|
and collision_circle(player.object.x, player.object.y, 50, Sentry, false, true) < 0
|
||||||
|
and player.object.nutsNBolts == 100
|
||||||
|
and (collision_point(player.object.x,player.object.y,SpawnRoom,0,0) < 0)
|
||||||
|
and !player.sentry
|
||||||
|
and !player.object.onCabinet)
|
||||||
|
{
|
||||||
|
write_ubyte(global.sendBuffer, BUILD_SENTRY);
|
||||||
|
write_ubyte(global.sendBuffer, playerId);
|
||||||
|
write_ushort(global.serializeBuffer, round(player.object.x*5));
|
||||||
|
write_ushort(global.serializeBuffer, round(player.object.y*5));
|
||||||
|
write_byte(global.serializeBuffer, player.object.image_xscale);
|
||||||
|
buildSentry(player, player.object.x, player.object.y, player.object.image_xscale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DESTROY_SENTRY:
|
||||||
|
with(player.sentry)
|
||||||
|
instance_destroy();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DROP_INTEL:
|
||||||
|
if (player.object != -1)
|
||||||
|
{
|
||||||
|
if (player.object.intel)
|
||||||
|
{
|
||||||
|
sendEventDropIntel(player);
|
||||||
|
doEventDropIntel(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OMNOMNOMNOM:
|
||||||
|
if(player.object != -1) {
|
||||||
|
if(!player.humiliated
|
||||||
|
and !player.object.taunting
|
||||||
|
and !player.object.omnomnomnom
|
||||||
|
and player.object.canEat
|
||||||
|
and player.class==CLASS_HEAVY)
|
||||||
|
{
|
||||||
|
write_ubyte(global.sendBuffer, OMNOMNOMNOM);
|
||||||
|
write_ubyte(global.sendBuffer, playerId);
|
||||||
|
with(player.object)
|
||||||
|
{
|
||||||
|
omnomnomnom = true;
|
||||||
|
if player.team == TEAM_RED {
|
||||||
|
omnomnomnomindex=0;
|
||||||
|
omnomnomnomend=31;
|
||||||
|
} else if player.team==TEAM_BLUE {
|
||||||
|
omnomnomnomindex=32;
|
||||||
|
omnomnomnomend=63;
|
||||||
|
}
|
||||||
|
xscale=image_xscale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TOGGLE_ZOOM:
|
||||||
|
if player.object != -1 {
|
||||||
|
if player.class == CLASS_SNIPER {
|
||||||
|
write_ubyte(global.sendBuffer, TOGGLE_ZOOM);
|
||||||
|
write_ubyte(global.sendBuffer, playerId);
|
||||||
|
toggleZoom(player.object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLAYER_CHANGENAME:
|
||||||
|
var nameLength;
|
||||||
|
nameLength = socket_receivebuffer_size(socket);
|
||||||
|
if(nameLength > MAX_PLAYERNAME_LENGTH)
|
||||||
|
{
|
||||||
|
write_ubyte(player.socket, KICK);
|
||||||
|
write_ubyte(player.socket, KICK_NAME);
|
||||||
|
socket_destroy(player.socket);
|
||||||
|
player.socket = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
with(player)
|
||||||
|
{
|
||||||
|
if(variable_local_exists("lastNamechange"))
|
||||||
|
if(current_time - lastNamechange < 1000)
|
||||||
|
break;
|
||||||
|
lastNamechange = current_time;
|
||||||
|
name = read_string(socket, nameLength);
|
||||||
|
if(string_count("#",name) > 0)
|
||||||
|
{
|
||||||
|
name = "I <3 Bacon";
|
||||||
|
}
|
||||||
|
write_ubyte(global.sendBuffer, PLAYER_CHANGENAME);
|
||||||
|
write_ubyte(global.sendBuffer, playerId);
|
||||||
|
write_ubyte(global.sendBuffer, string_length(name));
|
||||||
|
write_string(global.sendBuffer, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INPUTSTATE:
|
||||||
|
if(player.object != -1)
|
||||||
|
{
|
||||||
|
with(player.object)
|
||||||
|
{
|
||||||
|
keyState = read_ubyte(socket);
|
||||||
|
netAimDirection = read_ushort(socket);
|
||||||
|
aimDirection = netAimDirection*360/65536;
|
||||||
|
event_user(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REWARD_REQUEST:
|
||||||
|
player.rewardId = read_string(socket, socket_receivebuffer_size(socket));
|
||||||
|
player.challenge = rewardCreateChallenge();
|
||||||
|
|
||||||
|
write_ubyte(socket, REWARD_CHALLENGE_CODE);
|
||||||
|
write_binstring(socket, player.challenge);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REWARD_CHALLENGE_RESPONSE:
|
||||||
|
var answer, i, authbuffer;
|
||||||
|
answer = read_binstring(socket, 16);
|
||||||
|
|
||||||
|
with(player)
|
||||||
|
if(variable_local_exists("challenge") and variable_local_exists("rewardId"))
|
||||||
|
rewardAuthStart(player, answer, challenge, true, rewardId);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLUGIN_PACKET:
|
||||||
|
var packetID, buf, success;
|
||||||
|
|
||||||
|
packetID = read_ubyte(socket);
|
||||||
|
|
||||||
|
// get packet data
|
||||||
|
buf = buffer_create();
|
||||||
|
write_buffer_part(buf, socket, socket_receivebuffer_size(socket));
|
||||||
|
|
||||||
|
// try to enqueue
|
||||||
|
success = _PluginPacketPush(packetID, buf, player);
|
||||||
|
|
||||||
|
// if it returned false, packetID was invalid
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
// clear up buffer
|
||||||
|
buffer_destroy(buf);
|
||||||
|
|
||||||
|
// kick player
|
||||||
|
write_ubyte(player.socket, KICK);
|
||||||
|
write_ubyte(player.socket, KICK_BAD_PLUGIN_PACKET);
|
||||||
|
socket_destroy(player.socket);
|
||||||
|
player.socket = -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLIENT_SETTINGS:
|
||||||
|
var mirror;
|
||||||
|
mirror = read_ubyte(player.socket);
|
||||||
|
player.queueJump = mirror;
|
||||||
|
|
||||||
|
write_ubyte(global.sendBuffer, CLIENT_SETTINGS);
|
||||||
|
write_ubyte(global.sendBuffer, playerId);
|
||||||
|
write_ubyte(global.sendBuffer, mirror);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user