C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
// #define DEBUG
namespace Oxide.Plugins {
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
[Info("Commit Feed", "Jacob", "1.0.0")]
[Description("Displays new Rust commits to chat.")]
internal class CommitFeed : RustPlugin {
private const string Url = "https://rust.facepunch.com/rss/commits";
private Commit? _latestCommit;
private IEnumerable<Commit> ParseCommits(string xml) {
// HTML Regex: <div class=""change-entry"" id=""(?'id'\d+)"">\s*<div class=""time""><a href="".*"">(?'time'\d+:\d+)<\/a><\/div>\s*<div class=""change"">(?'change'[\w\s\S]*?)(?:<span class=""branch"" title=""branch name"">(?'branch'\/[\w\s\S]*?)<\/span>)?<\/div>\s*<\/div>
// TODO: parse the newly added author information
var matches = Regex.Matches(xml, @"<item><guid isPermaLink="".*?"">.*?<\/guid><link>.*?<\/link>.*?<title>(?'branch'.*?)\/(?'id'\d+)<\/title><description>(?'description'[\w\s\S]*?)<\/description>");
foreach (var groups in matches.Cast<Match>().Select(x => x.Groups)) {
var description = groups["description"].Value;
if (description == "Private") {
continue;
}
yield return new Commit {
Branch = groups["branch"].Value, Id = Convert.ToInt32(groups["id"].Value), Description = description
}
;
}
}
private void UpdateLatestCommit(IEnumerable<Commit> commits) {
_latestCommit = commits.OrderByDescending(x => x.Id).FirstOrDefault();
#if DEBUG
Console.WriteLine("Latest commit: " + JsonConvert.SerializeObject(_latestCommit));
#endif
}
protected override void LoadDefaultMessages() => lang.RegisterMessages(new Dictionary<string, string> {
["CommitAnnouncement"]
= "<size=16><color=#CD412B>Commit Feed</color></size>\n<size=13>{0}</size>", ["Error"] = $"Error fetching commits from \"{Url}.\""
}
, this);
private void OnServerInitialized() {
webrequest.Enqueue(Url, string.Empty, (code, xml) => {
if (code != 200) {
PrintWarning(lang.GetMessage("Error", this));
return;
}
UpdateLatestCommit(ParseCommits(xml));
}
, this);
timer.Every(60, () => {
webrequest.Enqueue(Url, string.Empty, (code, xml) => {
if (code != 200) {
PrintWarning(lang.GetMessage("Error", this));
return;
}
var newCommits = ParseCommits(xml).Where(x => x.Id > _latestCommit?.Id).ToArray();
if (!newCommits.Any()) {
return;
}
UpdateLatestCommit(newCommits);
foreach (var commit in newCommits) {
#if DEBUG
Console.WriteLine("New commit: " + JsonConvert.SerializeObject(commit));
#endif
foreach (var player in BasePlayer.activePlayerList) {
PrintToChat(player, lang.GetMessage("CommitAnnouncement", this, player.UserIDString), $"{commit.Description}\n#{commit.Id}, {commit.Branch}");
}
}
}
, this);
}
);
}
private struct Commit {
public string Branch {
get;
set;
}
public int Id {
get;
set;
}
public string Description {
get;
set;
}
}
}
}