Last active
October 4, 2020 16:33
-
-
Save MateusAquino/b2ca2ce5aa3de750e4f3080cf87a842c to your computer and use it in GitHub Desktop.
Código para bot de Discord (automute/link) [apenas moderadores]: pacotes udp entre cliente/servidor mais importantes foram mapeados com Regex. (Among Us v.2020.9.9s)
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
using System; | |
using System.IO; | |
using System.Text; | |
using System.Collections.Generic; | |
using System.Text.RegularExpressions; | |
using SharpPcap; | |
using System.Linq; | |
namespace Example5 | |
{ | |
public class Program | |
{ | |
public static void Main(string[] args) | |
{ | |
var devices = CaptureDeviceList.Instance; | |
if (devices.Count < 1) | |
{ | |
Console.WriteLine("No devices were found on this machine"); | |
return; | |
} | |
List<SharpPcap.Npcap.NpcapDevice> capturingDevices = new List<SharpPcap.Npcap.NpcapDevice>(); | |
foreach (SharpPcap.Npcap.NpcapDevice device in devices) | |
{ | |
device.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrival); | |
int readTimeoutMilliseconds = 500; | |
device.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds); | |
string filter = "udp"; | |
device.Filter = filter; | |
device.StartCapture(); | |
capturingDevices.Add(device); | |
} | |
Console.WriteLine("======= AutoAmong started ======="); | |
Console.ReadLine(); | |
foreach (SharpPcap.Npcap.NpcapDevice device in capturingDevices) | |
{ | |
device.StopCapture(); | |
device.Close(); | |
} | |
} | |
private static string GetStringFromByteArray(System.Byte[] byteArray) | |
{ | |
StringBuilder builder = new StringBuilder(); | |
for (int i = 0; i < byteArray.Length; i++) | |
{ | |
builder.Append(byteArray[i].ToString("x2")); | |
} | |
return builder.ToString(); | |
} | |
public static byte[] StringToByteArray(String hex) | |
{ | |
int NumberChars = hex.Length/2; | |
byte[] bytes = new byte[NumberChars]; | |
using (var sr = new StringReader(hex)) | |
{ | |
for (int i = 0; i < NumberChars; i++) | |
bytes[i] = | |
Convert.ToByte(new string(new char[2]{(char)sr.Read(), (char)sr.Read()}), 16); | |
} | |
return bytes; | |
} | |
public static string Skip(String data, int bytes) { | |
string hexString = ""; | |
for (int i = bytes*2; i < data.Length; i++) { hexString += data[i]; } | |
return hexString; | |
} | |
public static String getCorById(String id) { | |
int pos = Convert.ToInt32("0x"+id, 16); | |
string[] cores = { "vermelho", "azul escuro", "verde escuro", "rosa", "laranja", | |
"amarelo", "preto", "branco", "roxo", "marrom", "ciano", "verde claro" | |
}; | |
return cores[pos]; | |
} | |
public static String getNameFromData(String data, int skip) { | |
try { | |
data = Skip(data, skip); | |
byte[] dBytes = StringToByteArray(data); | |
string name = System.Text.Encoding.UTF8.GetString(dBytes); | |
string pattern = @"([\d\w\p{L} _]+)[\s\S]*$"; | |
var match = Regex.Match(name, pattern, RegexOptions.IgnoreCase); | |
return match.Groups[1].Value; | |
} catch (Exception) { | |
return ""; | |
} | |
} | |
public static string getNameFromData(String data) { | |
return getNameFromData(data, 12); | |
} | |
private static int logFromPort = 0; | |
private static List<string> orderedIds = new List<string>(); | |
private static Dictionary<string, string> players = new Dictionary<string, string>(); | |
private static bool logging = true; | |
// BITS MAPEADOS | |
static string criouPartida = @"^0800010046d20203..(.*)$"; | |
static string hostJoinColor = @"(?:0005.{6}000c.{16}|^.{8}0005.{6}8012.*?)0001.*08(..)[01]"; | |
static string acaoRealizada = @"0005.{6}80030002"; | |
static string trocouAparencia = @"0005.{6}80030002(..)(..)(..)..0002"; | |
static string matou = @"0005.{6}80030002(.{2})0c(.{2})"; // Grupo 1: id impostor | Grupo 2: id crewmate | |
static string reportou = @"0005.{6}80030002(.{2})0[be](.{2})$"; // Grupo 1: id reportou | Grupo 2: num morto | |
static string talvezEntrou = @"^..................80......"; | |
static string talvezRealmenteEntrou = @"....(..)"; | |
static string next0002 = @"^.*?0002"; | |
static string entrou = @"^(..)..(..)((?:..){charCount})......(.*?\2(?:..)?\3(..).*)$"; | |
static string saiu = @"0005.{6}80040002.{8}010005(..).{8}"; | |
static string saiuInGame = @"0005.{6}80010005(..)010005.{10}"; | |
static string fimVotacao = @"0005.{6}80020002"; | |
static string inicioVotacao = @"0005.{6}80030002.{4}ff"; | |
static string comecou = @"feffffff0f0001.{4}0001.{24}0000000.{146}"; | |
static string ejetadoOuSkippado = @"0005.{6}800f0002.{26}(..).{6}"; // Grupo 1: pessoa ejetada (numero), se g1 == 'ff': ent skippou | |
static string fimPartida = "0008.{6}800[0123]01$"; | |
static string entrouCamera = "500011380100100"; // EndsWith | |
static string andar = "00120005"; // StartsWith | |
private static void device_OnPacketArrival(object sender, CaptureEventArgs e) { | |
var packet = PacketDotNet.Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data); | |
var ipPacket = packet.Extract<PacketDotNet.IPPacket>(); | |
var udpPacket = packet.Extract<PacketDotNet.UdpPacket>(); | |
if (udpPacket == null || !udpPacket.HasPayloadData) return; | |
string data = GetStringFromByteArray(udpPacket.PayloadData); | |
if (data.Length < 11 || data.StartsWith(andar)) | |
return; | |
if (logging && udpPacket.SourcePort==logFromPort) | |
Console.WriteLine("☁️->"+data); | |
else if (logging && udpPacket.DestinationPort==logFromPort) | |
Console.WriteLine("☁️<-"+data); | |
//Console.WriteLine("+"+data); // LOGAR TUDO | |
if (Regex.IsMatch(data, criouPartida)) { | |
Console.WriteLine("-- Criou Partida --"); | |
var criou = Regex.Match(data, criouPartida, RegexOptions.IgnoreCase); | |
string hostname = getNameFromData(criou.Groups[1].Value, 0); | |
orderedIds.Add("HOST"); | |
players["HOST"] = hostname; | |
Console.WriteLine($" - {hostname} (HOST)"); | |
logFromPort = udpPacket.SourcePort; | |
} | |
else if (Regex.IsMatch(data, hostJoinColor)) { | |
var hjc = Regex.Match(data, hostJoinColor, RegexOptions.IgnoreCase); | |
string cor = getCorById(hjc.Groups[1].Value); | |
Console.WriteLine($"Host entrou com a cor {cor}"); | |
} | |
else if (Regex.IsMatch(data, saiu) || Regex.IsMatch(data, saiuInGame)) { | |
Match saiuComId; | |
string ingame = ""; | |
if (Regex.IsMatch(data, saiu)) | |
saiuComId = Regex.Match(data, saiu, RegexOptions.IgnoreCase); | |
else { | |
saiuComId = Regex.Match(data, saiuInGame, RegexOptions.IgnoreCase); | |
ingame = " - ingame"; | |
} | |
string id = saiuComId.Groups[1].Value; | |
string nome; | |
try { nome = players[id]; } catch (Exception) { nome = players["HOST"]; } | |
Console.WriteLine($" - {nome} saiu ({id}){ingame}"); | |
try { orderedIds.RemoveAll(playerSaiu=>playerSaiu.Equals(id)); } catch (Exception) {} | |
} | |
else if (Regex.IsMatch(data, fimPartida)) { | |
Console.WriteLine("-- Fim da partida --"); | |
string hostname = players["HOST"]; | |
orderedIds = new List<string>(); | |
players = new Dictionary<string, string>(); | |
orderedIds.Add("HOST"); | |
players["HOST"] = hostname; | |
} | |
else if (Regex.IsMatch(data, inicioVotacao)) { | |
Console.WriteLine("-- Início da Votação --"); | |
} | |
else if (Regex.IsMatch(data, fimVotacao)) { | |
Console.WriteLine("-- Fim da Votação --"); | |
} | |
else if (Regex.IsMatch(data, comecou)) { | |
Console.WriteLine("-- Partida começou --"); | |
orderedIds = orderedIds.Distinct().ToList(); | |
foreach (string id in orderedIds) | |
Console.WriteLine(players[id] + "->" + id); | |
} | |
else if (data.StartsWith(andar)) { | |
//Console.WriteLine("Alguém andou"); | |
} | |
else if (data.EndsWith(entrouCamera)) { | |
Console.WriteLine("Alguém entrou na camera"); | |
} | |
else if (Regex.IsMatch(data, ejetadoOuSkippado)) { | |
var eject = Regex.Match(data, ejetadoOuSkippado, RegexOptions.IgnoreCase); | |
if (eject.Groups[1].Value=="ff") | |
Console.WriteLine(" - Votação pulada"); | |
else { | |
int pos = Convert.ToInt32("0x"+eject.Groups[1].Value, 16); | |
string userejetado = players[orderedIds[pos]]; | |
Console.WriteLine($" - {userejetado} foi ejetado"); | |
} | |
} | |
else if (Regex.IsMatch(data, matou)) { | |
var kill = Regex.Match(data, matou, RegexOptions.IgnoreCase); | |
string impostor, impostorId = kill.Groups[1].Value; | |
string crewmate, crewmateId = kill.Groups[2].Value; | |
try { impostor = players[impostorId]; } catch (KeyNotFoundException) { impostor = players["HOST"]; } | |
try { crewmate = players[crewmateId]; } catch (KeyNotFoundException) { crewmate = players["HOST"]; } | |
Console.WriteLine($" - {impostor}({impostorId}) matou {crewmate}({crewmateId})"); | |
} | |
else if (Regex.IsMatch(data, reportou)) { | |
var report = Regex.Match(data, reportou, RegexOptions.IgnoreCase); | |
string impostor, impostorId = report.Groups[1].Value; | |
try { impostor = players[impostorId]; } catch (KeyNotFoundException) { impostor = players["HOST"]; } | |
Console.WriteLine($" - {impostor}({impostorId}) reportou um corpo."); | |
} | |
else { | |
didAdd = false; | |
if (Regex.IsMatch(data, talvezEntrou)) { | |
string players = Regex.Split(data, talvezEntrou)[1]; | |
getPlayerFromString(players); | |
} | |
if (didAdd) return; | |
if (Regex.IsMatch(data, trocouAparencia)) { | |
var troca = Regex.Match(data, trocouAparencia, RegexOptions.IgnoreCase); | |
string id = troca.Groups[1].Value; | |
string trocaTipo = troca.Groups[2].Value; | |
string trocaValor = troca.Groups[3].Value; | |
if (trocaTipo=="08") { // COR | |
string cor = getCorById(trocaValor); | |
string name = getNameFromData(data); | |
Console.WriteLine($" - {name} trocou a cor para: {cor}"); | |
} else if (trocaTipo=="09") { | |
//Console.WriteLine(" - Alguem mudou o chapeu"); | |
} else if (trocaTipo=="11") { | |
//Console.WriteLine(" - Alguem mudou o animal"); | |
} else if (trocaTipo=="0a") { | |
//Console.WriteLine(" - Alguem mudou o traje"); | |
} | |
} | |
else if (Regex.IsMatch(data, acaoRealizada)) { | |
string res = Regex.Split(data, acaoRealizada)[1]; | |
Console.WriteLine("Ação Não Mapeada: " + res); | |
} | |
} | |
} | |
public static bool didAdd = false; | |
public static bool getPlayerFromString(string playersStr) { | |
var charCount = Regex.Match(playersStr, talvezRealmenteEntrou).Groups[1].Value; | |
try { Convert.ToInt32("0x"+charCount, 16); } catch(Exception) { return false; } | |
int qntCharsName = Convert.ToInt32("0x"+charCount, 16); | |
var pRgxStr = entrou.Replace("charCount", $"{qntCharsName}"); | |
Regex playerRgx = new Regex(pRgxStr, RegexOptions.Compiled); | |
var player = playerRgx.Match(playersStr); | |
if (player.Success) { | |
var id = player.Groups[1].Value; | |
var name = getNameFromData(player.Groups[3].Value, 0); | |
var color = player.Groups[5].Value; | |
var tryContinuing = player.Groups[4].Value; | |
bool nomeValido = Regex.IsMatch(name.Trim(), @"^[0-9 A-Za-zÀ-ÖØ-öø-ÿ]{1,10}$", RegexOptions.IgnoreCase); | |
bool corValida = Regex.IsMatch(color.Trim(), @"^0[0-9ab]$", RegexOptions.IgnoreCase); | |
if (name.Trim()!="" && nomeValido && corValida) { | |
if (!(orderedIds.Contains(id) && players[id]==name)) { | |
Console.WriteLine($" - {name} entrou ({id}) com a cor {getCorById(color)}"); | |
orderedIds.Add(id); | |
players[id] = name; | |
} | |
didAdd = true; | |
} | |
bool keepTrying = false; | |
bool worked; | |
do { | |
worked = getPlayerFromString(tryContinuing); | |
keepTrying = Regex.IsMatch(tryContinuing, next0002); | |
if (keepTrying) tryContinuing = Regex.Split(tryContinuing, next0002)[1]; | |
} while (!worked && keepTrying); | |
return true; | |
} else { | |
if (Regex.IsMatch(playersStr, next0002)) | |
return getPlayerFromString(Regex.Split(playersStr, next0002)[1]); | |
} | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment