Commit 29f844aa authored by Senator John's avatar Senator John 💬

Merge branch 'patch' into 'master'

Patch

See merge request !28
parents 2a369a96 08a8d2c2
......@@ -346,6 +346,10 @@ MonoBehaviour:
listOpRemoved: {fileID: 21300000, guid: 066065a6b1b767c418d2889597305402, type: 3}
listMyXyz: {fileID: 21300000, guid: dcbfe2b5c52ef9c45a945e6099f96860, type: 3}
listOpXyz: {fileID: 21300000, guid: dc626d3f4895db448969ee261eac22c6, type: 3}
listSingleColumn: {fileID: 21300000, guid: 1593fc89217af42499c6ab1514ab1709, type: 3}
listViewIconExpand: {fileID: 21300000, guid: 838190b6b8c45334bab89da28a238150, type: 3}
listViewIconDefault: {fileID: 21300000, guid: 9f9e97c267d35b84db512595c857ffba, type: 3}
listCardStatsBase: {fileID: 21300000, guid: 5b696a850bf3a3443bf0e67396ecc181, type: 3}
CardAffectDisable: {fileID: 21300000, guid: 5e4f5281aaf73274c888adbe5afce0e0, type: 3}
CardAffectEquip: {fileID: 21300000, guid: 1a678cbbdf93a5449aa105d7c2d6d83a, type: 3}
CardAffectField: {fileID: 21300000, guid: 4185642e1b53a404ea1e358e5ccda6fe, type: 3}
......
......@@ -99,6 +99,9 @@ namespace MDPro3.Duel
UIManager.UIBlackIn(Core.TransitionTime);
await UniTask.WaitForSeconds(Core.TransitionTime);
await UniTask.WaitUntil(() => Appearance.loaded);
// Rebuild appearance assets on each match load so random selections
// (icon / frame / protector) are re-rolled per duel.
await Program.instance.appearance.LoadSettingAssets();
await ABLoader.CacheMasterDuelBundles();
Program.instance.ocgcore.LoadDuelButton();
......
......@@ -255,7 +255,7 @@ namespace MDPro3
manager.GetElement("PropertyMonster").SetActive(false);
manager.GetElement("PropertySpell").SetActive(true);
manager.GetElement<Image>("SpellType").sprite = TextureManager.GetSpellTrapTypeIcon(data);
manager.GetElement<Text>("TextSpellType").text = data.GetSpellTrapType();
manager.GetElement<Text>("TextSpellType").text = data.GetSpellTrapType(true);
}
RefreshLimitIcon(data.Id);
}
......
This diff is collapsed.
......@@ -656,13 +656,13 @@ namespace MDPro3.Duel
MessageManager.Cast(InterString.Get("请联系开发者修复这张特殊胜利的卡。"));
}
// Start win/lose field animation first, then show result text while it is ongoing.
duelBGManager.ShowBGEnd(duelResult);
await duelBGManager.ShowDuelResultText(duelText);
MessageManager.Cast(endingReason);
if (condition != Condition.Replay)
Core.GetUI<OcgCoreUI>().ShowSaveReplay();
duelBGManager.ShowBGEnd(duelResult);
}
protected override UniTask GameMessage_UpdateData(BinaryReader reader)
......
......@@ -8,6 +8,8 @@ namespace MDPro3.Duel.YGOSharp
public IList<int> BannedIds { get; private set; }
public IList<int> LimitedIds { get; private set; }
public IList<int> SemiLimitedIds { get; private set; }
public IList<int> UnlimitedIds { get; private set; }
public bool WhitelistOnly { get; private set; }
public uint Hash { get; private set; }
public string Name = "";
......@@ -16,6 +18,8 @@ namespace MDPro3.Duel.YGOSharp
BannedIds = new List<int>();
LimitedIds = new List<int>();
SemiLimitedIds = new List<int>();
UnlimitedIds = new List<int>();
WhitelistOnly = false;
Hash = 0x7dfcee6a;
}
......@@ -37,7 +41,9 @@ namespace MDPro3.Duel.YGOSharp
return 1;
if (SemiLimitedIds.Contains(cardId))
return 2;
if (UnlimitedIds.Contains(cardId))
return 3;
return WhitelistOnly ? 0 : 3;
}
else
{
......@@ -47,14 +53,24 @@ namespace MDPro3.Duel.YGOSharp
return 1;
if (SemiLimitedIds.Contains(al))
return 2;
if (UnlimitedIds.Contains(al))
return 3;
return WhitelistOnly ? 0 : 3;
}
}
public void EnableWhitelistMode()
{
if (WhitelistOnly)
return;
WhitelistOnly = true;
Hash ^= 0x0f0f0f0f;
}
public void Add(int cardId, int quantity)
{
if (quantity < 0 || quantity > 2)
if (quantity < 0 || quantity > 3)
return;
switch (quantity)
{
......@@ -67,6 +83,9 @@ namespace MDPro3.Duel.YGOSharp
case 2:
SemiLimitedIds.Add(cardId);
break;
case 3:
UnlimitedIds.Add(cardId);
break;
}
uint code = (uint)cardId;
Hash = Hash ^ ((code << 18) | (code >> 14)) ^ ((code << (27 + quantity)) | (code >> (5 - quantity)));
......
using Ionic.Zip;
using MDPro3.Servant;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace MDPro3.Duel.YGOSharp
{
......@@ -9,6 +11,9 @@ namespace MDPro3.Duel.YGOSharp
{
public static List<Banlist> Banlists { get; private set; }
public static string EmptyBanlistName = "N/A";
private static bool localServerLflistInjected;
private static string localServerLflistBackupContent;
private const string LfListFileName = "lflist.conf";
public static void Initialize()
{
......@@ -54,6 +59,110 @@ namespace MDPro3.Duel.YGOSharp
Banlists.Add(current);
}
public static void PrepareLocalServerLflist()
{
if (localServerLflistInjected)
return;
if (!Config.GetBool("Expansions", true))
return;
try
{
if (!File.Exists(Program.PATH_LFLIST))
return;
localServerLflistBackupContent = File.ReadAllText(Program.PATH_LFLIST);
var mergedContent = BuildMergedLflistContent();
if (string.IsNullOrEmpty(mergedContent) || mergedContent == localServerLflistBackupContent)
{
localServerLflistBackupContent = null;
return;
}
File.WriteAllText(Program.PATH_LFLIST, mergedContent);
localServerLflistInjected = true;
}
catch (Exception e)
{
localServerLflistBackupContent = null;
localServerLflistInjected = false;
UnityEngine.Debug.LogError("Failed to prepare LAN lflist.conf.");
UnityEngine.Debug.LogException(e);
}
}
public static void RestoreLocalServerLflist()
{
if (!localServerLflistInjected)
return;
try
{
if (localServerLflistBackupContent != null)
File.WriteAllText(Program.PATH_LFLIST, localServerLflistBackupContent);
}
catch (Exception e)
{
UnityEngine.Debug.LogError("Failed to restore original lflist.conf.");
UnityEngine.Debug.LogException(e);
}
finally
{
localServerLflistBackupContent = null;
localServerLflistInjected = false;
}
}
private static string BuildMergedLflistContent()
{
StringBuilder builder = new StringBuilder();
var confPath = Program.PATH_EXPANSIONS + LfListFileName;
AppendLflistFromFile(builder, confPath);
foreach (var zip in ZipHelper.zips)
{
if (zip.Name.ToLower().EndsWith("script.zip"))
continue;
foreach (var file in zip.EntryFileNames)
{
if (!file.ToLower().EndsWith(LfListFileName))
continue;
var entry = zip[file];
using (var memoryStream = new MemoryStream())
{
entry.Extract(memoryStream);
memoryStream.Position = 0;
using (var reader = new StreamReader(memoryStream))
AppendLflistText(builder, reader.ReadToEnd());
}
}
}
AppendLflistFromFile(builder, Program.PATH_LFLIST);
return builder.ToString();
}
private static void AppendLflistFromFile(StringBuilder builder, string path)
{
if (!File.Exists(path))
return;
AppendLflistText(builder, File.ReadAllText(path));
}
private static void AppendLflistText(StringBuilder builder, string text)
{
if (string.IsNullOrWhiteSpace(text))
return;
if (builder.Length > 0 && builder[builder.Length - 1] != '\n')
builder.AppendLine();
builder.Append(text);
if (builder.Length > 0 && builder[builder.Length - 1] != '\n')
builder.AppendLine();
}
public static void InitializeFromReader(StreamReader reader)
{
Banlist current = null;
......@@ -73,6 +182,12 @@ namespace MDPro3.Duel.YGOSharp
Banlists.Add(current);
continue;
}
if (line.StartsWith("$"))
{
if (current != null && line.Equals("$whitelist", StringComparison.OrdinalIgnoreCase))
current.EnableWhitelistMode();
continue;
}
if (!line.Contains(" "))
continue;
if (current == null)
......
using System.Runtime.InteropServices;
using System.Threading;
using MDPro3.Duel.YGOSharp;
namespace MDPro3.Net
{
......@@ -20,16 +21,30 @@ namespace MDPro3.Net
StopServer();
serverThread = new Thread(() =>
{
try
{
Dll.start_server(args);
}
finally
{
BanlistManager.RestoreLocalServerLflist();
}
});
serverThread.Start();
}
public static void StopServer()
{
try
{
Dll.stop_server();
}
finally
{
serverThread?.Abort();
BanlistManager.RestoreLocalServerLflist();
}
}
public static bool ServerRunning()
......
......@@ -25,8 +25,8 @@ namespace MDPro3
public static void Initialize()
{
translations.Clear();
translationsForRender.Clear();
translationsForPrerelease.Clear();
translationsForRender = new Dictionary<string, string>();
translationsForPrerelease = new Dictionary<string, string>();
path = Program.PATH_LOCALES + Language.GetConfig() + PATH_CONF_FILE;
if (!File.Exists(path))
......
......@@ -298,6 +298,10 @@ namespace MDPro3
public Sprite listOpRemoved;
public Sprite listMyXyz;
public Sprite listOpXyz;
public Sprite listSingleColumn;
public Sprite listViewIconExpand;
public Sprite listViewIconDefault;
public Sprite listCardStatsBase;
[Header("Card Affect")]
public Sprite CardAffectDisable;
......
......@@ -131,6 +131,7 @@ namespace MDPro3.Servant
public static float nextNegateAction_AdditionalTime;
public static ElementObjectManager nextNegateAction_AdditionalManager;
public static Action startCard;
public Action onSurrenderConfirmed;
public static Material myProtector;
public static Material opProtector;
......@@ -653,11 +654,13 @@ namespace MDPro3.Servant
InterString.Get("是"),
InterString.Get("否")
};
UIManager.ShowPopupYesOrNo(selections, ActionSurrender, null);
UIManager.ShowPopupYesOrNo(selections, ActionSurrender, ActionCancelSurrender);
}
private void ActionSurrender()
{
onSurrenderConfirmed?.Invoke();
onSurrenderConfirmed = null;
surrendered = true;
if (TcpHelper.tcpClient != null && TcpHelper.tcpClient.Connected)
{
......@@ -670,6 +673,11 @@ namespace MDPro3.Servant
OnExit();
}
private void ActionCancelSurrender()
{
onSurrenderConfirmed = null;
}
#endregion
#region Message
......
......@@ -51,6 +51,8 @@ namespace MDPro3.Servant
if (servantUI != null)
RefreshDeckSelector();
// Re-roll random duel icon/frame/protector whenever returning to lobby.
_ = Program.instance.appearance.LoadSettingAssets();
StartCoroutine(RefreshMyCardAssets());
}
......@@ -145,6 +147,7 @@ namespace MDPro3.Servant
RoomServant.FromLocalHost = true;
RoomServant.FromHandTest = false;
BanlistManager.PrepareLocalServerLflist();
YgoServer.StartServer(args);
TcpHelper.LinkStart("127.0.0.1", Config.Get("DuelPlayerName0", Config.EMPTY_STRING), port.ToString(), string.Empty, true, null);
}
......
......@@ -67,6 +67,8 @@ namespace MDPro3.Servant
CoreShowing = 0;
Program.instance.ui_.chatPanel.Show(false);
OcgCore.handler = Handler;
// Re-roll random duel/watch icon & frame whenever entering a room.
_ = Program.instance.appearance.LoadSettingAssets();
GetUI<RoomServantUI>().RefreshDeckSelector();
}
......
......@@ -47,6 +47,17 @@ namespace MDPro3.Servant
[HideInInspector] public SelectionToggle_Solo lastSoloItem;
private string lastSoloCommand = string.Empty;
private int lastSoloPort = 7911;
private int lastSoloLp = 8000;
private int lastSoloHand = 5;
private int lastSoloDraw = 1;
private bool lastSoloLockHand;
private bool lastSoloNoCheck;
private bool lastSoloNoShuffle;
private bool hasLastSoloLaunchConfig;
private bool retryLastSoloDuelWhenShown;
#region Servant
public override int Depth => 3;
......@@ -59,6 +70,13 @@ namespace MDPro3.Servant
LoadBots();
}
protected override void ApplyShowArrangement(int preDepth)
{
base.ApplyShowArrangement(preDepth);
if (retryLastSoloDuelWhenShown)
StartCoroutine(RetryLastSoloDuelWhenReady());
}
protected override void FirstLoadEvent()
{
base.FirstLoadEvent();
......@@ -164,7 +182,19 @@ namespace MDPro3.Servant
{
string aiCommand = GetWindBotCommand(aiCode, diyDeck);
if (!string.IsNullOrEmpty(aiCommand))
Launch(aiCommand, GetUI<SoloSelectorUI>().IsLockHand(), GetUI<SoloSelectorUI>().IsNoCheck(), GetUI<SoloSelectorUI>().IsNoShuffle());
{
var ui = GetUI<SoloSelectorUI>();
var lockHand = ui.IsLockHand();
var noCheck = ui.IsNoCheck();
var noShuffle = ui.IsNoShuffle();
var duelPort = ui.GetPort();
var duelLp = ui.GetLP();
var duelHand = ui.GetHand();
var duelDraw = ui.GetDraw();
RememberLastSoloLaunch(aiCommand, duelPort, duelLp, duelHand, duelDraw, lockHand, noCheck, noShuffle);
LaunchWithConfig(aiCommand, duelPort, duelLp, duelHand, duelDraw, lockHand, noCheck, noShuffle);
}
}
public void StartAIForRoom(int aiCode, bool diyDeck)
......@@ -229,13 +259,60 @@ namespace MDPro3.Servant
}
public void Launch(string command, bool lockHand, bool noCheck, bool noShuffle)
{
port = GetUI<SoloSelectorUI>().GetPort().ToString();
var ui = GetUI<SoloSelectorUI>();
LaunchWithConfig(command, ui.GetPort(), ui.GetLP(), ui.GetHand(), ui.GetDraw(), lockHand, noCheck, noShuffle);
}
public bool CanRetryLastSoloDuel()
{
return hasLastSoloLaunchConfig;
}
public void QueueRetryLastSoloDuel()
{
if (!CanRetryLastSoloDuel())
return;
retryLastSoloDuelWhenShown = true;
}
private void RememberLastSoloLaunch(string command, int duelPort, int duelLp, int duelHand, int duelDraw
, bool lockHand, bool noCheck, bool noShuffle)
{
lastSoloCommand = command;
lastSoloPort = duelPort;
lastSoloLp = duelLp;
lastSoloHand = duelHand;
lastSoloDraw = duelDraw;
lastSoloLockHand = lockHand;
lastSoloNoCheck = noCheck;
lastSoloNoShuffle = noShuffle;
hasLastSoloLaunchConfig = true;
}
private IEnumerator RetryLastSoloDuelWhenReady()
{
yield return null;
while (showing && inTransition)
yield return null;
if (!showing || !retryLastSoloDuelWhenShown || !hasLastSoloLaunchConfig)
yield break;
retryLastSoloDuelWhenShown = false;
LaunchWithConfig(lastSoloCommand, lastSoloPort, lastSoloLp, lastSoloHand, lastSoloDraw
, lastSoloLockHand, lastSoloNoCheck, lastSoloNoShuffle);
}
private void LaunchWithConfig(string command, int duelPort, int duelLp, int duelHand, int duelDraw
, bool lockHand, bool noCheck, bool noShuffle)
{
port = duelPort.ToString();
string lp = GetUI<SoloSelectorUI>().GetLP().ToString();
string hand = GetUI<SoloSelectorUI>().GetHand().ToString();
string draw = GetUI<SoloSelectorUI>().GetDraw().ToString();
string lp = duelLp.ToString();
string hand = duelHand.ToString();
string draw = duelDraw.ToString();
string args = port + " -1 5 0 F " + (noCheck ? "T " : "F ") + (noShuffle ? "T " : "F ") + lp + " " + hand + " " + draw + " 0 0";
if (TcpHelper.IsPortAvailable(int.Parse(port)))
if (TcpHelper.IsPortAvailable(duelPort))
{
YgoServer.StartServer(args);
RoomServant.FromSolo = true;
......
......@@ -419,7 +419,7 @@ namespace MDPro3.UI
SpellTrapType.SetActive(true);
IconSpellTrapType.sprite = TextureManager.container.GetCardSpellTrapTypeIcon(data);
TextSpellTrapType.text
= StringHelper.SecondType(data.Type) + StringHelper.MainType(data.Type);
= data.GetSpellTrapType(true);
IconAtk.gameObject.SetActive(false);
IconDef.gameObject.SetActive(false);
......
......@@ -234,8 +234,7 @@ namespace MDPro3.UI
cardCollectionView.superScrollView.scrollRect.OnBeginDrag(eventData);
dragStartPosition = eventData.position;
dragProcessing = true;
//draging = !DeckEditor.useMobileLayout;
draging = false;
draging = !DeckEditor.UseMobileLayout;
dragIni = false;
}
......
......@@ -46,6 +46,7 @@ namespace MDPro3.UI
public string description;
public string path;
private bool loaded;
private Material protectorMaterial;
private Coroutine refreshCoroutine;
private Coroutine hideCoroutine;
......@@ -71,8 +72,13 @@ namespace MDPro3.UI
if (path.StartsWith("Protector"))
{
Protector.material = await ABLoader.LoadProtectorMaterial(itemID.ToString(), destroyCancellationToken);
Protector.material.renderQueue = 3000;
protectorMaterial = await ABLoader.LoadProtectorMaterial(itemID.ToString(), destroyCancellationToken);
if (protectorMaterial != null)
protectorMaterial.renderQueue = 3000;
// Use default UI material for list rendering so viewport/mask clipping works while scrolling.
Protector.texture = protectorMaterial == null ? null : protectorMaterial.mainTexture;
Protector.material = null;
Protector.color = Color.white;
Icon.gameObject.SetActive(false);
}
......@@ -150,7 +156,7 @@ namespace MDPro3.UI
{
DeckEditor.Deck.Protector = itemID;
Program.instance.deckEditor.GetUI<DeckEditorUI>().DeckView.SetDirty(true);
Program.instance.deckEditor.GetUI<DeckEditorUI>().IconProtector.material = Protector.material;
Program.instance.deckEditor.GetUI<DeckEditorUI>().IconProtector.material = protectorMaterial;
}
}
else if (path.StartsWith("FieldIcon"))
......@@ -211,38 +217,38 @@ namespace MDPro3.UI
if (Appearance.player == "0")
{
if (Appearance.condition == Appearance.Condition.Duel)
Appearance.duelProtector0 = Protector.material;
Appearance.duelProtector0 = protectorMaterial;
else if (Appearance.condition == Appearance.Condition.Watch)
Appearance.watchProtector0 = Protector.material;
Appearance.watchProtector0 = protectorMaterial;
else if (Appearance.condition == Appearance.Condition.Replay)
Appearance.replayProtector0 = Protector.material;
Appearance.replayProtector0 = protectorMaterial;
}
else if (Appearance.player == "1")
{
if (Appearance.condition == Appearance.Condition.Duel)
Appearance.duelProtector1 = Protector.material;
Appearance.duelProtector1 = protectorMaterial;
else if (Appearance.condition == Appearance.Condition.Watch)
Appearance.watchProtector1 = Protector.material;
Appearance.watchProtector1 = protectorMaterial;
else if (Appearance.condition == Appearance.Condition.Replay)
Appearance.replayProtector1 = Protector.material;
Appearance.replayProtector1 = protectorMaterial;
}
else if (Appearance.player == "0Tag")
{
if (Appearance.condition == Appearance.Condition.Duel)
Appearance.duelProtector0Tag = Protector.material;
Appearance.duelProtector0Tag = protectorMaterial;
else if (Appearance.condition == Appearance.Condition.Watch)
Appearance.watchProtector0Tag = Protector.material;
Appearance.watchProtector0Tag = protectorMaterial;
else if (Appearance.condition == Appearance.Condition.Replay)
Appearance.replayProtector0Tag = Protector.material;
Appearance.replayProtector0Tag = protectorMaterial;
}
else if (Appearance.player == "1Tag")
{
if (Appearance.condition == Appearance.Condition.Duel)
Appearance.duelProtector1Tag = Protector.material;
Appearance.duelProtector1Tag = protectorMaterial;
else if (Appearance.condition == Appearance.Condition.Watch)
Appearance.watchProtector1Tag = Protector.material;
Appearance.watchProtector1Tag = protectorMaterial;
else if (Appearance.condition == Appearance.Condition.Replay)
Appearance.replayProtector1Tag = Protector.material;
Appearance.replayProtector1Tag = protectorMaterial;
}
}
else
......
......@@ -547,6 +547,7 @@ namespace MDPro3.UI.ServantUI
public override void Initialize(Servant.Servant servant)
{
base.Initialize(servant);
ButtonRetry.SetClickEvent(OnRetry);
InitializeVolume();
InitializeScreenMode();
......@@ -609,7 +610,10 @@ namespace MDPro3.UI.ServantUI
ToggleWatch.gameObject.SetActive(false);
ToggleReplay.gameObject.SetActive(false);
ButtonRetry.gameObject.SetActive(false);
var canRetrySolo = RoomServant.FromSolo;
ButtonRetry.gameObject.SetActive(canRetrySolo);
if (canRetrySolo)
ButtonRetry.SetButtonText(InterString.Get("重试"));
ButtonSurrender.gameObject.SetActive(true);
ButtonSurrender.SetButtonText(InterString.Get("投降"));
}
......@@ -2387,6 +2391,17 @@ namespace MDPro3.UI.ServantUI
Program.instance.ocgcore.OnDuelResultConfirmed(true);
}
public void OnRetry()
{
if (OcgCore.condition != OcgCore.Condition.Duel || !RoomServant.FromSolo)
return;
if (!Program.instance.solo.CanRetryLastSoloDuel())
return;
Program.instance.ocgcore.onSurrenderConfirmed = Program.instance.solo.QueueRetryLastSoloDuel;
Program.instance.ocgcore.OnDuelResultConfirmed(true);
}
}
public partial class SROptions
......
......@@ -410,7 +410,7 @@ namespace MDPro3.UI
ParamatorAreaBottom.SetActive(false);
SpellTrapType.SetActive(true);
IconSpellTrapType.sprite = TextureManager.container.GetCardSpellTrapTypeIcon(data);
TextSpellTrapType.text = data.GetSpellTrapType();
TextSpellTrapType.text = data.GetSpellTrapType(true);
PoolGroup.SetParent(ParamatorAreaTop.transform, false);
}
......
......@@ -428,7 +428,7 @@ namespace MDPro3.UI
{
SpellTrapType.SetActive(true);
IconSpellTrapType.sprite = TextureManager.container.GetCardSpellTrapTypeIcon(data);
TextSpellTrapType.text = data.GetSpellTrapType();
TextSpellTrapType.text = data.GetSpellTrapType(true);
IconAtk.gameObject.SetActive(false);
IconDef.gameObject.SetActive(false);
......
......@@ -7,6 +7,8 @@ namespace YGOSharp
public IList<int> BannedIds { get; private set; }
public IList<int> LimitedIds { get; private set; }
public IList<int> SemiLimitedIds { get; private set; }
public IList<int> UnlimitedIds { get; private set; }
public bool WhitelistOnly { get; private set; }
public uint Hash { get; private set; }
public Banlist()
......@@ -14,6 +16,8 @@ namespace YGOSharp
BannedIds = new List<int>();
LimitedIds = new List<int>();
SemiLimitedIds = new List<int>();
UnlimitedIds = new List<int>();
WhitelistOnly = false;
Hash = 0x7dfcee6a;
}
......@@ -25,12 +29,22 @@ namespace YGOSharp
return 1;
if (SemiLimitedIds.Contains(cardId))
return 2;
if (UnlimitedIds.Contains(cardId))
return 3;
return WhitelistOnly ? 0 : 3;
}
public void EnableWhitelistMode()
{
if (WhitelistOnly)
return;
WhitelistOnly = true;
Hash ^= 0x0f0f0f0f;
}
public void Add(int cardId, int quantity)
{
if (quantity < 0 || quantity > 2)
if (quantity < 0 || quantity > 3)
return;
switch (quantity)
{
......@@ -43,6 +57,9 @@ namespace YGOSharp
case 2:
SemiLimitedIds.Add(cardId);
break;
case 3:
UnlimitedIds.Add(cardId);
break;
}
uint code = (uint)cardId;
Hash = Hash ^ ((code << 18) | (code >> 14)) ^ ((code << (27 + quantity)) | (code >> (5 - quantity)));
......
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
namespace YGOSharp
......@@ -25,6 +26,12 @@ namespace YGOSharp
Banlists.Add(current);
continue;
}
if (line.StartsWith("$"))
{
if (current != null && line.Equals("$whitelist", StringComparison.OrdinalIgnoreCase))
current.EnableWhitelistMode();
continue;
}
if (!line.Contains(" "))
continue;
if (current == null)
......
fileFormatVersion: 2
guid: 5b696a850bf3a3443bf0e67396ecc181
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WindowsStoreApps
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 9f9e97c267d35b84db512595c857ffba
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WindowsStoreApps
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 838190b6b8c45334bab89da28a238150
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WindowsStoreApps
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment