Created
November 30, 2015 06:58
-
-
Save arctic5/509daee07a8980c87e9f to your computer and use it in GitHub Desktop.
chat security fixes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
global.chatSendBuffer = buffer_create(); | |
global.chatPacketID = argument1; | |
global.chatLog = ds_list_create(); | |
ds_list_add(global.chatLog,"OLorgan3's chat plugin v3 - press T to show/hide,"); | |
ds_list_add(global.chatLog,"OY to chat and U to teamchat"); | |
global.chatBanlist = ds_list_create(); | |
global.consoleFont = font_add("Lucida Console",8,0,0,32,127); | |
global.chatSprite = sprite_add(argument0+"/ConsoleWindowS.png",2,0,0,0,0); | |
//global variables | |
ini_open("gg2.ini"); | |
global.chatGlobal = ini_read_real("Plugins","chat_global",ord('Y')); | |
global.chatTeam = ini_read_real("Plugins","chat_team",ord('U')); | |
global.chatToggle = ini_read_real("Plugins","chat_toggle",ord('T')); | |
ini_close(); | |
//make a new menu for plugin options | |
if !variable_global_exists("pluginOptions") { | |
global.pluginOptions = object_add(); | |
object_set_parent(global.pluginOptions,OptionsController); | |
object_set_depth(global.pluginOptions,-130000); | |
object_event_add(global.pluginOptions,ev_create,0,' | |
menu_create(40, 140, 300, 200, 30); | |
if room != Options { | |
menu_setdimmed(); | |
} | |
menu_addback("Back", " | |
instance_destroy(); | |
if(room == Options) | |
instance_create(0,0,MainMenuController); | |
else | |
instance_create(0,0,InGameMenuController); | |
"); | |
'); | |
object_event_add(InGameMenuController,ev_create,0,' | |
menu_addlink("Plugin Options", " | |
instance_destroy(); | |
instance_create(0,0,global.pluginOptions); | |
"); | |
'); | |
} | |
object_event_add(global.pluginOptions,ev_create,0,' | |
menu_addedit_key("Global chat","global.chatGlobal",""); | |
menu_addedit_key("Team chat","global.chatTeam",""); | |
menu_addedit_key("Toggle chatwindow","global.chatToggle",""); | |
'); | |
object_event_add(global.pluginOptions,ev_destroy,0,' | |
ini_open("gg2.ini"); | |
ini_write_real("Plugins","chat_global",global.chatGlobal); | |
ini_write_real("Plugins","chat_team",global.chatTeam); | |
ini_write_real("Plugins","chat_toggle",global.chatToggle); | |
ini_close(); | |
'); | |
execute_file(directory + '/lorganbase.gml'); | |
ds_list_add(lorganbase_plugins, 'chat_v2'); | |
//create the new object | |
object_event_add(lorganbase,ev_step,ev_step_begin,'if !instance_exists(global.chatWindow) instance_create(0,0,global.chatWindow);'); | |
//set a variable to detect players with chat | |
object_event_add(Player,ev_create,0,' | |
hasChat = false; | |
nameBkp = ""; | |
lastChatTime = 0; | |
chatCount = 0; | |
'); | |
//because server-sent plugins do weird things on startup: | |
object_event_add(Player,ev_step,ev_step_begin,' | |
//this only gets executed for host. | |
if !variable_local_exists("hasChat") { | |
hasChat = false; | |
nameBkp = ""; | |
lastChatTime = 0; | |
chatCount = 0; | |
} | |
if global.isHost { | |
if name != nameBkp { | |
var count, length; | |
count = 0; | |
length = min(18,string_length(name)); | |
//change the new name so that no players have the same name. | |
with(Player) { | |
if string_lower(string_copy(other.name,0,length)) == string_lower(string_copy(name,0,length)) count += 1; | |
} | |
if count > 1 { //there are other people with the same name | |
name = string_copy(name,0,length)+string(count); | |
write_ubyte(global.sendBuffer, PLAYER_CHANGENAME); | |
write_ubyte(global.sendBuffer, ds_list_find_index(global.players,id)); | |
write_ubyte(global.sendBuffer, string_length(name)); | |
write_string(global.sendBuffer, name); | |
} | |
if nameBkp == "" { | |
nameBkp = name; | |
exit; | |
} | |
if hasChat || global.myself == id { | |
global.chatWindow._player = id; | |
with(global.chatWindow) { | |
_message = "O"+other.nameBkp+" has changed their name to "+other.name+"."; | |
_team = 0; | |
event_user(2); //tell everyone someone changed names | |
event_user(4); //add to own chat | |
event_user(7); //prevent spamming | |
} | |
nameBkp = name; | |
} | |
} | |
} | |
'); | |
//send a message to the server to tell that we have the chat plugin | |
object_event_add(PlayerControl,ev_create,0," | |
if !global.isHost { | |
write_ubyte(global.chatSendBuffer,0); //hello | |
PluginPacketSend(global.chatPacketID,global.chatSendBuffer); | |
buffer_clear(global.chatSendBuffer); | |
} | |
"); | |
//add the new object, set depth and set persistent | |
if !variable_global_exists('chatWindow') global.chatWindow = object_add(); //Other plugins may have run before and already injected code. | |
object_set_depth(global.chatWindow, -110002); | |
object_set_persistent(global.chatWindow,true); | |
//initialize | |
object_event_add(global.chatWindow,ev_create,0,' | |
sprite_index = global.chatSprite; | |
open = false; | |
hidden = true; | |
team = false; | |
offset = 0; | |
image_speed = 0; | |
idle = false; | |
'); | |
object_event_add(global.chatWindow,ev_alarm,0," | |
idle = true; | |
"); | |
//All main stuff happens here | |
object_event_add(global.chatWindow,ev_step,ev_step_end,' | |
x = view_xview[0]+7; | |
y = view_yview[0]+340; | |
if (!instance_exists(InGameMenuController) && !instance_exists(OptionsController) && !instance_exists(ControlsController) && !instance_exists(HUDOptionsController)) || instance_exists(global.cheatycheat) { | |
if keyboard_check_pressed(global.chatToggle) && !open { | |
if !open hidden = !hidden; | |
idle = false; | |
alarm[0]=120; | |
} else if keyboard_check_pressed(global.chatGlobal) && !open { | |
open = true; | |
hidden = false; | |
keyboard_string=""; | |
team = false; | |
instance_create(0,0,global.cheatycheat); | |
} else if keyboard_check_pressed(global.chatTeam) && global.myself.team != TEAM_SPECTATOR && !open { | |
open = true; | |
hidden = false; | |
keyboard_string=""; | |
team = true; | |
instance_create(0,0,global.cheatycheat); | |
} else if open && keyboard_check_pressed(vk_enter) { | |
with(global.cheatycheat) instance_destroy(); | |
if keyboard_string != "" { | |
_message = keyboard_string; | |
if global.isHost { | |
_player = global.myself; | |
if team == true _team = global.myself.team+1; | |
else _team = 0 | |
event_user(1); //process our own message | |
event_user(2); //send our own message to the clients | |
event_user(4); //add our own message to the chatbox | |
} else { | |
_team = team; | |
event_user(3); //send a message as a client | |
} | |
keyboard_string=""; | |
} | |
open = false; | |
team = false; | |
idle = false; | |
alarm[0]=120; | |
} | |
} | |
if open { | |
image_index = 1; | |
if (keyboard_check_pressed(vk_up) or mouse_wheel_up()) && ds_list_size(global.chatLog) > 9 offset = min(ds_list_size(global.chatLog)-10,offset+1); | |
else if keyboard_check_pressed(vk_down) or mouse_wheel_down() offset = max(0,offset-1); | |
} else image_index = 0; | |
if global.isHost { | |
event_user(0); //forward messages as a host | |
} else event_user(6); //read messages as a client | |
'); | |
//draw | |
object_event_add(global.chatWindow,ev_draw,0,' | |
var xoffset, yoffset, xsize, ysize, index; | |
xsize = sprite_width; | |
ysize = sprite_height; | |
draw_set_valign(fa_top); | |
draw_set_halign(fa_left); | |
draw_set_color(c_white); | |
draw_set_alpha(1); | |
draw_set_font(global.consoleFont); | |
if !hidden draw_sprite_ext(sprite_index,image_index,x,y,1,1,0,c_white,0.8); | |
//prevent too long strings | |
if open { | |
keyboard_string = string_copy(keyboard_string,1,230); //limit messages | |
//make that the text doesnt go outside the chatwindow | |
if string_length(keyboard_string)-53 > 0 index = string_length(keyboard_string)-52; | |
else index = 0; | |
chatmessage = string_copy(keyboard_string,index,53); | |
if team == 1 { | |
if global.myself.team == TEAM_BLUE message="B"; | |
else message = "R"; | |
event_user(5); | |
} | |
draw_text(x + 3, y+ysize-15, chatmessage); | |
} | |
// The drawing of the text | |
var amount; | |
if !hidden amount = min(ds_list_size(global.chatLog),10); | |
else if !idle amount = min(ds_list_size(global.chatLog),2); | |
else amount = 0; | |
for(i=0;i<amount;i+=1) { | |
message = ds_list_find_value(global.chatLog, ds_list_size(global.chatLog)-amount+i-offset); | |
pos = string_pos("#",message); | |
if pos == 0 { | |
event_user(5); //read the color code | |
draw_text(x+10, y+ysize-40-12*(amount-i),string_copy(message,2,255)); | |
} else { | |
event_user(5); //read the color code | |
prefix = string_copy(message,2,pos-1); | |
draw_text(x+10, y+ysize-40-12*(amount-i),prefix); | |
message = string_copy(message,pos+1,255); | |
event_user(5); //read the next color code | |
draw_text(x+10+string_width(prefix), y+ysize-40-12*(amount-i),string_copy(message,2,255)); | |
} | |
} | |
draw_set_font(global.gg2Font); | |
'); | |
//Use some events as scripts | |
//event0 : process input as a host | |
object_event_add(global.chatWindow,ev_other,ev_user0,' | |
while(PluginPacketGetBuffer(global.chatPacketID) != -1) { | |
chatReceiveBuffer = PluginPacketGetBuffer(global.chatPacketID); | |
switch(read_ubyte(chatReceiveBuffer)) { | |
case 0: //hello | |
_player = PluginPacketGetPlayer(global.chatPacketID); | |
if (ds_list_find_index(global.chatBanlist,socket_remote_ip(_player.socket)) == -1 && !_player.hasChat) { //ignore muted players | |
_player.hasChat = true; | |
_player.nameBkp = _player.name; | |
_message = "O"+_player.name+" has joined chat!"; | |
_team = 0; | |
event_user(2); //tell everyone someone joined chat | |
event_user(4); //add to own chat | |
} | |
break; | |
case 1: //global chat | |
_player = PluginPacketGetPlayer(global.chatPacketID); | |
if _player.hasChat { | |
_team = 0; | |
_len = read_ubyte(chatReceiveBuffer); | |
_message = read_string(chatReceiveBuffer,_len); | |
event_user(1); //process a message | |
event_user(2); //send | |
event_user(4); //add to chatwindow | |
event_user(7); //prevent spamming | |
} | |
break; | |
case 2: //team chat | |
_player = PluginPacketGetPlayer(global.chatPacketID); | |
if _player.team != TEAM_SPECTATOR && _player.hasChat { | |
_team = 1+_player.team; | |
_len = read_ubyte(chatReceiveBuffer); | |
_message = read_string(chatReceiveBuffer,_len); | |
event_user(1); //process a message | |
event_user(2); //send | |
if global.myself.team == TEAM_SPECTATOR || _team == global.myself.team+1 event_user(4); //add to chatwindow | |
event_user(7); //prevent spamming | |
} | |
break; | |
} | |
buffer_clear(chatReceiveBuffer); | |
PluginPacketPop(global.chatPacketID); | |
} | |
'); | |
//event1 : process a message as host | |
object_event_add(global.chatWindow,ev_other,ev_user1,' | |
_message = string_replace_all(_message,"#"," "); | |
if _player.team == TEAM_RED _color = "R"; | |
else if _player.team == TEAM_BLUE _color = "B"; | |
else _color = "W"; | |
if _team == 0 { | |
if _player.id == global.myself _message = _color+_player.name+": #O"+_message; | |
else _message = _color+_player.name+": #W"+_message; | |
} else { | |
_message = _color+_player.name+": "+_message; | |
} | |
'); | |
//event2 : send a message as host | |
object_event_add(global.chatWindow,ev_other,ev_user2,' | |
write_ubyte(global.chatSendBuffer,min(255,string_length(_message))); | |
write_string(global.chatSendBuffer,string_copy(_message,0,255)); | |
with(Player) { | |
if hasChat = true { | |
if other._team > 0 && team == other._team-1 || other._team == 0 { | |
PluginPacketSendTo(global.chatPacketID,global.chatSendBuffer, id); | |
} | |
} | |
} | |
buffer_clear(global.chatSendBuffer); | |
'); | |
//event3 : send a message as a client | |
object_event_add(global.chatWindow,ev_other,ev_user3,' | |
write_ubyte(global.chatSendBuffer,_team+1); | |
write_ubyte(global.chatSendBuffer,min(255,string_length(_message))); | |
write_string(global.chatSendBuffer,string_copy(_message,0,255)); | |
PluginPacketSend(global.chatPacketID,global.chatSendBuffer); | |
buffer_clear(global.chatSendBuffer); | |
'); | |
//event4 : add messages to the chatwindow | |
object_event_add(global.chatWindow,ev_other,ev_user4,' | |
//make the window display the new message | |
alarm[0]=120; | |
idle = false; | |
while(string_length(_message) != 0) { | |
if string_length(_message) > 53 { | |
ds_list_add(global.chatLog,string_copy(_message,1,53)); | |
pos = string_pos("#",_message); | |
if pos == 0 color = string_copy(_message,1,1); | |
else color = string_copy(_message,pos+1,1); | |
_message = color+string_copy(_message,54,255); | |
} else { | |
ds_list_add(global.chatLog,string_copy(_message,1,53)); | |
_message = ""; | |
} | |
} | |
'); | |
//event5 : read the color code | |
object_event_add(global.chatWindow,ev_other,ev_user5,' | |
switch(string_copy(message,1,1)) { | |
case "R": | |
//draw_set_color(make_color_rgb(205,0,0)); | |
draw_set_color(make_color_rgb(237,61,61)); | |
break; | |
case "B": | |
draw_set_color(make_color_rgb(61,135,218)); | |
break | |
case "O": | |
draw_set_color(c_orange); | |
break; | |
default: draw_set_color(c_white); | |
} | |
'); | |
//event6 : read messages as a client | |
object_event_add(global.chatWindow,ev_other,ev_user6,' | |
while(PluginPacketGetBuffer(global.chatPacketID) != -1) { | |
chatReceiveBuffer = PluginPacketGetBuffer(global.chatPacketID); | |
_len = read_ubyte(chatReceiveBuffer); | |
_message = read_string(chatReceiveBuffer,_len); | |
event_user(4); //add to chatwindow | |
buffer_clear(chatReceiveBuffer); | |
PluginPacketPop(global.chatPacketID); | |
} | |
'); | |
//event7 : check if the player isn't spamming | |
//this event can also be used by other plugins to read each message! | |
object_event_add(global.chatWindow,ev_other,ev_user7,' | |
if _player.lastChatTime > current_time-2000 { | |
_player.chatCount += 1; | |
if _player.chatCount > 5 { | |
//mute player. | |
_message = "O"+_player.name+" has been muted due to spamming."; | |
_team = 0; | |
event_user(2); //tell everyone someone got muted | |
event_user(4); //add to own chat | |
_player.hasChat = false; | |
ds_list_add(global.chatBanlist,socket_remote_ip(_player.socket)); | |
} | |
} else _player.chatCount = 1; | |
_player.lastChatTime = current_time; | |
'); | |
//create a cheaty cheat object to prevent you from moving and opening chat menus while typing :p | |
global.cheatycheat = object_add(); | |
object_set_parent(global.cheatycheat,InGameMenuController); | |
object_event_add(global.cheatycheat,ev_step,ev_step_normal,'//no'); | |
object_event_add(global.cheatycheat,ev_draw,0,'//no'); | |
object_event_add(global.cheatycheat,ev_keypress,vk_enter,'//no'); | |
object_event_add(global.cheatycheat,ev_keypress,vk_escape,' | |
with(global.chatWindow) open = false; | |
instance_create(0,0,InGameMenuController); | |
instance_destroy(); | |
'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment