287 lines
12 KiB
C#
287 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Web;
|
|
using JD.Asset.Types.Map;
|
|
using JD.Core;
|
|
using JD.Serialization;
|
|
using TeaBox.Gui;
|
|
using TeaBox.Macros;
|
|
using TeaBox.Shotgun;
|
|
using TeaBox.SourceControl;
|
|
using TeaBox.Utilities.Secrets;
|
|
|
|
namespace TeaBox.TechCellToolbox
|
|
{
|
|
[Module, Category(@"Data\TechCell ToolBox"), DisplayName("SongDesc")]
|
|
class BatchEditFile
|
|
{
|
|
// string that must be added to every credits
|
|
private const string _legalCredits =
|
|
@" All rights of the producer and other rightholders to the recorded work reserved. Unless otherwise authorized, the duplication, rental, loan, exchange or use of this video game for public performance, broadcasting and online distribution to the public are prohibited.";
|
|
|
|
public enum IntensityLevels
|
|
{
|
|
Cool,
|
|
Intense,
|
|
Extreme
|
|
}
|
|
|
|
[Macro]
|
|
[DisplayName("Set Intensity Level")]
|
|
[Description("Set map intensity tag in songdesc")]
|
|
public void SetMapIntensity(IExecutionContext context, MapList maps, IntensityLevels intensity,
|
|
[Description("Remove intensity tag from songdesc")] bool remove)
|
|
{
|
|
Changelist changelist;
|
|
SourceControlService.Instance.Data()
|
|
.CreateChangelist("[Teabox]batch edit songdesc", out changelist);
|
|
var perforceCommandContext = new CommandExecutionContext(context, changelist);
|
|
|
|
var stringIntensity = "";
|
|
switch (intensity)
|
|
{
|
|
case IntensityLevels.Intense:
|
|
stringIntensity = "Intense";
|
|
break;
|
|
case IntensityLevels.Extreme:
|
|
stringIntensity = "Extreme";
|
|
break;
|
|
case IntensityLevels.Cool:
|
|
stringIntensity = "Cool";
|
|
break;
|
|
}
|
|
foreach (var map in maps)
|
|
{
|
|
SourceControlService.Instance.Data()
|
|
.Checkout(perforceCommandContext, new[] { PathEntry.FromFile(map.SongDescPath) });
|
|
var actorTemplate = (Actor_Template)Serializers.LuaSerializer.LoadObjectFromFile(map.SongDescPath);
|
|
var songDesc = actorTemplate.COMPONENTS.OfType<JD_SongDescTemplate>().First();
|
|
|
|
RemoveIntensityTag(context, songDesc);
|
|
if (!remove) songDesc.Tags.Add(new StringID(stringIntensity));
|
|
|
|
|
|
Serializers.LuaSerializer.SaveObjectToFile(actorTemplate, map.SongDescPath);
|
|
}
|
|
}
|
|
|
|
// Remove INtensity tag from songdesc
|
|
public void RemoveIntensityTag(IExecutionContext context, JD_SongDescTemplate songDesc)
|
|
{
|
|
if (songDesc.Tags.Contains(new StringID("Cool"))) songDesc.Tags.Remove(new StringID("Cool"));
|
|
if (songDesc.Tags.Contains(new StringID("Intense"))) songDesc.Tags.Remove(new StringID("Intense"));
|
|
if (songDesc.Tags.Contains(new StringID("Extreme"))) songDesc.Tags.Remove(new StringID("Extreme"));
|
|
}
|
|
|
|
// Retrieve maps' title from shotgun
|
|
public string GetTitleFromShotgun(Map map)
|
|
{
|
|
var sClient = ShotgunClientExtensions.DefaultClient();
|
|
var sgMap = sClient.FindOne<ShotgunMap>(new { map.Name });
|
|
return sgMap.MapTitle;
|
|
}
|
|
|
|
// return an array containing any map's legal info gathered in plm : [title, artist name, credits]
|
|
public string[] PlmLegalInfo(IExecutionContext context, Map map)
|
|
{
|
|
const string user = "wedance-capture";
|
|
string password = ServiceAccounts.GetServiceAccountPassword(user);
|
|
|
|
var title = GetTitleFromShotgun(map);
|
|
var client = new WebClient { Credentials = new NetworkCredential(user, password) };
|
|
|
|
var mapId = GetMapId(title, client, context);
|
|
|
|
var artist = "no artist";
|
|
var coverArtist = "no artist";
|
|
var credits = "no credits";
|
|
var raw = client.DownloadString($@"https://plm/Song/Edit/{mapId}");
|
|
var separator = new[] { "<tr", "<td", "span", "<script>" }; // to split the html file into large parts
|
|
var listContent = raw.Split(separator, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
|
foreach (var content in listContent)
|
|
{
|
|
separator = new[] { ">", "<" }; // to split the html big parts into smaller parts
|
|
|
|
if (content.Contains(@"artist-name"))
|
|
{
|
|
var tempArray = content.Split(separator, StringSplitOptions.RemoveEmptyEntries);
|
|
artist = HttpUtility.HtmlDecode(tempArray[tempArray.IndexOf("/") - 1]);
|
|
}
|
|
|
|
if (content.Contains(@"id=""CoverArtistName"""))
|
|
{
|
|
separator = new[] { "\"", "<", " />" };
|
|
var tempArray = content.Split(separator, StringSplitOptions.RemoveEmptyEntries);
|
|
coverArtist = HttpUtility.HtmlDecode(tempArray.Last());
|
|
}
|
|
|
|
if (!content.Contains(@"id=""Credits""")) continue;
|
|
{
|
|
var tempArray = content.Split(separator, StringSplitOptions.RemoveEmptyEntries);
|
|
credits = HttpUtility.HtmlDecode(tempArray[tempArray.IndexOf("/textarea") - 1]
|
|
.Trim())
|
|
.Replace("\r\n", ". ")
|
|
.Replace("\r", ". ")
|
|
.Replace("\n", ". ")
|
|
.Replace(".. ", ". ")
|
|
.Replace("–", "-")
|
|
.Replace("“", "“")
|
|
.Replace("’", "'")
|
|
.Replace("â€", "”")
|
|
.Replace("Å", "ō")
|
|
;
|
|
|
|
if (!credits.Contains(_legalCredits))
|
|
{
|
|
credits = string.Concat(credits, " ", _legalCredits);
|
|
}
|
|
|
|
// validation dialog
|
|
var dialog = new MessageDialog
|
|
{
|
|
MainIcon = MessageDialogIcon.Warning,
|
|
MainMessage = $"{map.Name} credits\n{credits}",
|
|
};
|
|
dialog.AddButton("Keep it");
|
|
var leave = dialog.AddButton("Leave it");
|
|
var result = dialog.ShowDialog();
|
|
|
|
if (result == leave)
|
|
{
|
|
credits = null;
|
|
}
|
|
// validation dialog - end
|
|
}
|
|
}
|
|
if (coverArtist != @" value=") artist = coverArtist;
|
|
|
|
return new[] { title, artist, credits };
|
|
}
|
|
|
|
// retrieve the PLM Id from the PLMIDList.txt file or browse plm to update the file.
|
|
public int GetMapId(string title, WebClient client, IExecutionContext context)
|
|
{
|
|
title = title.Replace("'", @"'");
|
|
SourceControlService.Instance.Data()
|
|
.GetRevision(GetRevisionOptions.Force,
|
|
new[] { PathEntry.FromFile($@"{DataRoot.Value}/EngineData/Maplists/Common/PlmIdList.txt") });
|
|
|
|
var id = 0;
|
|
var lastId = 0;
|
|
var plmIdList = $@"{DataRoot.Value}/EngineData/Maplists/Common/PlmIdList.txt";
|
|
var idList = System.IO.File.ReadAllLines(plmIdList).ToList();
|
|
|
|
// Look for the map in the PLMIDList.txt
|
|
foreach (var idLine in idList)
|
|
{
|
|
var couple = idLine.Split(';');
|
|
lastId = int.Parse(couple[0]);
|
|
if (couple[1] != title) continue;
|
|
id = lastId;
|
|
break;
|
|
}
|
|
|
|
if (id != 0) return id;
|
|
|
|
// id still 0 : got to browse PLM to find map's id and update the List file with all browsed maps
|
|
context.LogWarning("updating idlist");
|
|
Changelist plmchangelist;
|
|
SourceControlService.Instance.Data().CreateChangelist("PLMidList update", out plmchangelist);
|
|
var perforceCommandContext = new CommandExecutionContext(context, plmchangelist);
|
|
SourceControlService.Instance.Data().Checkout(perforceCommandContext, new[] { PathEntry.FromFile(plmIdList) });
|
|
|
|
for (var i = lastId + 1; i < 7000; i++)
|
|
{
|
|
var page = client.DownloadString($@"https://plm/Song/Edit/{i}");
|
|
var pageTitle = ExtractPlmTitle(page);
|
|
idList.Add($@"{i};{pageTitle}");
|
|
System.IO.File.WriteAllLines(plmIdList, idList);
|
|
|
|
|
|
|
|
if (!pageTitle.Contains(title)) continue;
|
|
SourceControlService.Instance.Data().Submit(plmchangelist, SubmitOptions.SubmitUnchanged);
|
|
return i;
|
|
}
|
|
|
|
SourceControlService.Instance.Data().Submit(plmchangelist, SubmitOptions.SubmitUnchanged);
|
|
context.LogError("Id not found in PLM");
|
|
return 0;
|
|
}
|
|
|
|
// return map's plm ID from his plm web page
|
|
public static string ExtractPlmTitle(string page)
|
|
{
|
|
// <span class="song-name">Chiwawa</span>
|
|
var splitPage = page.Split('<', '>');
|
|
return HttpUtility.HtmlDecode(splitPage[splitPage.IndexOf(@"span class=""song-name""") + 1]);
|
|
}
|
|
|
|
|
|
[Macro]
|
|
[DisplayName("Update From PLM")]
|
|
[Description("Update songDesc with PLM credits and artist name, get title from shotgun")]
|
|
public void WriteLegalInfoInSongdesc(IExecutionContext context, MapList maps)
|
|
{
|
|
Changelist changelist;
|
|
SourceControlService.Instance.Data()
|
|
.CreateChangelist($@"[Teabox]{MaplistToP4Tag(maps)} Update song info", out changelist);
|
|
var perforceCommandContext = new CommandExecutionContext(context, changelist);
|
|
foreach (var map in maps)
|
|
{
|
|
|
|
SourceControlService.Instance.Data()
|
|
.GetRevision(GetRevisionOptions.Force, new[] { PathEntry.FromFile(map.SongDescPath) });
|
|
var actorTemplate = (Actor_Template)Serializers.LuaSerializer.LoadObjectFromFile(map.SongDescPath);
|
|
var songDesc = actorTemplate.COMPONENTS.OfType<JD_SongDescTemplate>().First();
|
|
SourceControlService.Instance.Data()
|
|
.Checkout(perforceCommandContext, new[] { PathEntry.FromFile(map.SongDescPath) });
|
|
|
|
|
|
var legalInfo = PlmLegalInfo(context, map);
|
|
songDesc.Title = legalInfo[0];
|
|
songDesc.Artist = legalInfo[1];
|
|
if (songDesc.Credits != null) songDesc.Credits = legalInfo[2];
|
|
|
|
Serializers.LuaSerializer.SaveObjectToFile(actorTemplate, map.SongDescPath);
|
|
context.LogWarning($@"""{map.Name}"" updated");
|
|
}
|
|
SubmitDialog(changelist);
|
|
}
|
|
|
|
|
|
public string MaplistToP4Tag(MapList maps)
|
|
{
|
|
return maps.Count > 4 ? "[Multimap]" : maps.Aggregate("", (current, map) => string.Concat(current, "[", map.Name, "]"));
|
|
}
|
|
|
|
// ask user to submit changes
|
|
public void SubmitDialog(Changelist changelist)
|
|
{
|
|
var dialog = new MessageDialog
|
|
{
|
|
MainIcon = MessageDialogIcon.Information,
|
|
MainMessage = "Submit changes to P4?",
|
|
};
|
|
var submit = dialog.AddButton("Submit");
|
|
dialog.AddButton("Keep changelist");
|
|
var revert = dialog.AddButton("Revert changelist");
|
|
var result = dialog.ShowDialog();
|
|
|
|
if (result == submit)
|
|
{
|
|
SourceControlService.Instance.Data().Submit(changelist, SubmitOptions.SubmitUnchanged);
|
|
}
|
|
if (result == revert)
|
|
{
|
|
SourceControlService.Instance.Data().RevertChangelist(changelist, RevertOptions.None, new List<PathEntry>());
|
|
SourceControlService.Instance.Data().DeleteChangeList(changelist);
|
|
}
|
|
}
|
|
}
|
|
}
|