async Task ProcessAsync(HttpListenerContext ctx) { if (ctx.Request.UserAgent != "osu!") { return; } if (ctx.Request.Url.AbsolutePath.StartsWith("/web/")) { return; } if (string.IsNullOrEmpty(ctx.Request.Headers["osu-token"])) { await Login.Handle(ctx); return; } Player p = Global.FindPlayer(ctx.Request.Headers["osu-token"]); if (p == null) // if they arent part of the player collection, force them to relogin { ctx.Response.StatusCode = 403; ctx.Response.OutputStream.Write(Packets.Packets.SingleIntPacket(5, -5)); ctx.Response.Close(); return; } using (MemoryStream ms = new MemoryStream()) using (BinaryReader r = new BinaryReader(ms)) { await ctx.Request.InputStream.CopyToAsync(ms); ms.Position = 0; while (ms.Position < ctx.Request.ContentLength64 - 6) { short Id = r.ReadInt16(); ms.Position += 1; int Length = r.ReadInt32(); if (ms.Position + Length > ctx.Request.ContentLength64) { break; } if (Id == 68 || Id == 79) { ms.Position += Length; continue; } byte[] Data = r.ReadBytes(Length); switch (Id) { case 4: p.Ping = DateTime.Now.Ticks; break; case 0: StatusUpdate.Handle(p, Data); break; case 1: IrcMessage.Handle(p, Data); break; case 2: Player.RemovePlayer(p); break; case 3: await StatsUpdateRequest.Handle(p); break; case 16: StartSpectating.Handle(p, Data); break; case 17: StopSpectating.Handle(p); break; case 18: SpectatorFrames.Handle(p, Data); break; case 25: IrcMessage.HandlePrivate(p, Data); break; case 29: Global.LeaveLobby(p); break; case 30: Global.JoinLobby(p); break; case 31: CreateMatch.Handle(p, Data); break; case 32: JoinMatch.Handle(p, Data); break; case 33: LeaveMatch.Handle(p); break; case 38: ChangeSlot.Handle(p, Data); break; case 39: MatchReady.Handle(p); break; case 40: SlotLock.Handle(p, Data); break; case 41: MatchSettings.Handle(p, Data); break; case 44: MatchStart.Handle(p, Data); break; case 49: MatchFinished.Handle(p); break; case 51: ModsChange.Handle(p, Data); break; case 52: MatchLoaded.Handle(p); break; case 54: NoBeatmap.Handle(p); break; case 55: MatchReady.Handle(p); break; case 56: MatchFailed.Handle(p); break; case 59: HasBeatmap.Handle(p); break; case 60: MatchSkip.Handle(p); break; case 63: ChannelJoinEvent.Handle(p, Data); break; case 70: ChangeHost.Handle(p, Data); break; case 73: AddFriend.Handle(p, Data); break; case 74: RemoveFriend.Handle(p, Data); break; case 77: ChangeTeam.Handle(p, Data); break; case 78: ChannelLeaveEvent.Handle(p, Data); break; case 85: StatsUpdateRequest.Handle(p, Data); break; case 90: MatchChangePassword.Handle(p, Data); break; default: Log.LogFormat($"%#FFFF%Unhandled Packet {Id} with {Length}"); break; } } } if (p.StreamLength != 0) { p.StreamCopyTo(ctx.Response.OutputStream); } ctx.Response.Close(); }
public static void ImportLogs(string characterName) { var characterPath = Path.Combine(App.DataDirectory, characterName); var slimcatPath = Path.Combine(slimCatRoaming, characterName); var eventSerializerSettings = new JsonSerializerSettings { Converters = new JsonConverter[] { new LogManager.CharacterConverter(null), new LogManager.ChannelMemberConverter(null), new LogManager.ChannelConverter() }, TypeNameHandling = TypeNameHandling.Auto, SerializationBinder = new LogManager.EventSerializationBinder() }; var serializer = new MessageSerializer(null); foreach (var dir in Directory.EnumerateDirectories(slimcatPath)) { var name = Path.GetFileName(dir); var files = Directory.GetFiles(dir, "*.txt").Select(x => { try { var date = Path.GetFileNameWithoutExtension(x).Split('-').Select(int.Parse).ToArray(); return(new { Name = x, Date = new DateTime(date[2], date[0], date[1]) }); } catch { return(null); } }).Where(x => x != null).OrderBy(x => x.Date); if (name == "!Notifications") { var events = new StreamWriter(Path.Combine(characterPath, "EventLog")); foreach (var file in files) { foreach (var line in GetLogEntries(File.ReadLines(file.Name), eventRegex)) { try { Match match; Event e = null; DateTime GetTime() { var time = match.Groups[1].Value; return(file.Date.AddMinutes(int.Parse(time.Substring(0, 2)) * 60 + int.Parse(time.Substring(3)))); } if ((match = statusRegex.Match(line)).Success) { var status = match.Groups[4].Success ? match.Groups[4].Value.ToEnum <StatusEnum>() : StatusEnum.Online; e = new StatusEvent(new Character(match.Groups[2].Value), status, match.Groups[6].Value, GetTime()); } else if ((match = loginRegex.Match(line)).Success) { e = new LoginEvent(new Character(match.Groups[2].Value), GetTime()); } else if ((match = logoutRegex.Match(line)).Success) { e = new LogoutEvent(new Character(match.Groups[2].Value), GetTime()); } else if ((match = joinRegex.Match(line)).Success) { e = new ChannelJoinEvent(new Channel(null, match.Groups[3].Value, null), new Channel.Member(new Character(match.Groups[2].Value)), GetTime()); } else if ((match = leaveRegex.Match(line)).Success) { e = new ChannelLeaveEvent(new Channel(null, match.Groups[3].Value, null), new Channel.Member(new Character(match.Groups[2].Value)), GetTime()); } else if ((match = descriptionRegex.Match(line)).Success) { continue; } else if ((match = opChangeRegex.Match(line)).Success) { continue; } else if ((match = openRegex.Match(line)).Success) { continue; } else if ((match = listRegex.Match(line)).Success) { continue; } else if ((match = friendRegex.Match(line)).Success) { continue; } else if ((match = kickRegex.Match(line)).Success) { continue; } else if ((match = noteRegex.Match(line)).Success) { e = new NoteEvent(new Character(match.Groups[2].Value), null, match.Groups[3].Value, GetTime()); } else if ((match = broadcastRegex.Match(line)).Success) { e = new BroadcastEvent(new Character(match.Groups[2].Value), match.Groups[3].Value, GetTime()); } else if ((match = mentionRegex.Match(line)).Success) { var time = GetTime(); e = new MentionEvent(new Channel(null, match.Groups[4].Value, null), new Message(Message.Type.Message, new Character(match.Groups[2].Value), time, match.Groups[5].Value), GetTime()); } else if ((match = inviteRegex.Match(line)).Success) { e = new InviteEvent(new Character(match.Groups[2].Value), new ChannelListItem(match.Groups[4].Value, match.Groups[3].Value, 0), GetTime()); } if (e != null) { events.WriteLine(JsonConvert.SerializeObject(e, typeof(Event), Formatting.None, eventSerializerSettings)); } } catch {} } } events.Dispose(); continue; } Stream logs = null, ads = null, logsIndex = null, adsIndex = null; var parenIndex = name.IndexOf('('); var logDir = Path.Combine(characterPath, parenIndex != -1 ? $"#{name.Substring(parenIndex + 1, name.Length - parenIndex - 2)}" : officialChannels.Contains(name) ? $"#{name}" : name); if (Directory.Exists(logDir)) { continue; } Directory.CreateDirectory(logDir); foreach (var file in files) { var logsIndexed = false; var adsIndexed = false; foreach (var line in GetLogEntries(File.ReadLines(file.Name), logRegex)) { try { var index = 0; var type = Message.Type.Message; string sender; if (line.StartsWith("Ad at")) { type = Message.Type.Ad; index += 6; } var h = int.Parse(line.Substring(index + 1, 2)); var m = int.Parse(line.Substring(index + 4, 2)); index += 8; var text = ""; if (type == Message.Type.Ad) { var end = line.LastIndexOf("~By "); if (end != -1) { text = line.Substring(index, end - index); sender = line.Substring(end + 4); } else { sender = characterRegex.Match(line, index, Math.Min(20, line.Length - index)).Groups[1].Value; index += sender.Length; text = index < line.Length ? line.Substring(index) : ""; } } else { if (line[index] == '[') { type = Message.Type.Roll; var end = line.IndexOf('[', index); sender = line.Substring(index, end - index); } else { if (index + characterName.Length <= line.Length && line.Substring(index, characterName.Length) == characterName) { sender = characterName; } else if (index + name.Length <= line.Length && line.Substring(index, name.Length) == name) { sender = name; } else { sender = characterRegex.Match(line, index, Math.Min(20, line.Length - index)).Groups[1].Value; } index += sender.Length; if (index < line.Length) { if (line[index] == ':') { index += 1; if (index < line.Length && line[index] == ' ') { index += 1; } } else { type = Message.Type.Action; } } } text += index < line.Length ? line.Substring(index) : ""; } var stream = type == Message.Type.Ad ? (ads ?? (ads = File.OpenWrite(Path.Combine(logDir, "Ads")))) : (logs ?? (logs = File.OpenWrite(Path.Combine(logDir, "Logs")))); if (type == Message.Type.Ad) { if (!adsIndexed) { serializer.WriteIndex(adsIndex ?? (adsIndex = File.OpenWrite(Path.Combine(logDir, "Ads.idx"))), file.Date, stream.Position); adsIndexed = true; } } else { if (!logsIndexed) { serializer.WriteIndex(logsIndex ?? (logsIndex = File.OpenWrite(Path.Combine(logDir, "Logs.idx"))), file.Date, stream.Position); logsIndexed = true; } } if (sender.Length > 20) { sender = sender.Substring(0, 20); } serializer.Write(stream, new Message(type, new Character(sender), file.Date.AddMinutes(h * 60 + m), text)); } catch { } } } logs?.Dispose(); ads?.Dispose(); logsIndex?.Dispose(); adsIndex?.Dispose(); } }