Make build .psu file!
This commit is contained in:
parent
94baeb74d8
commit
0fbf9e96c9
|
@ -10,11 +10,10 @@ namespace LibW4M.Data.Stats
|
||||||
{
|
{
|
||||||
public class TeamStatsCollective : SaveDataCollective
|
public class TeamStatsCollective : SaveDataCollective
|
||||||
{
|
{
|
||||||
public List<XomString> TeamNames;
|
public List<XomString> TeamNames = new List<XomString>();
|
||||||
|
|
||||||
public TeamStatsCollective(W4SaveFile fileBelongs, XomContainer mainContainer) : base(fileBelongs, mainContainer)
|
public TeamStatsCollective(W4SaveFile fileBelongs, XomContainer mainContainer) : base(fileBelongs, mainContainer)
|
||||||
{
|
{
|
||||||
TeamNames = new List<XomString>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Load()
|
public override void Load()
|
||||||
|
@ -44,8 +43,6 @@ namespace LibW4M.Data.Stats
|
||||||
|
|
||||||
this.collectiveEntries.Add(stats);
|
this.collectiveEntries.Add(stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Save()
|
public override void Save()
|
||||||
|
@ -84,7 +81,7 @@ namespace LibW4M.Data.Stats
|
||||||
|
|
||||||
|
|
||||||
// add team names too
|
// add team names too
|
||||||
newCollective[teamStatsStart] = teamNamesLen;
|
newCollective[teamNamesStart] = teamNamesLen;
|
||||||
for (int i = 0; i < teamNamesLen; i++)
|
for (int i = 0; i < teamNamesLen; i++)
|
||||||
newCollective[teamNamesStart + i + 1] = this.TeamNames[i].Id;
|
newCollective[teamNamesStart + i + 1] = this.TeamNames[i].Id;
|
||||||
|
|
||||||
|
|
|
@ -21,33 +21,10 @@ namespace LibW4M.Data.Teams
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private int weaponContainerId;
|
|
||||||
private int clusterContainerId;
|
|
||||||
|
|
||||||
|
|
||||||
public WeaponData SecretWeapon
|
public WeaponData SecretWeapon;
|
||||||
{
|
public WeaponData SecretWeaponCluster;
|
||||||
get
|
|
||||||
{
|
|
||||||
return fileBelongs.findWeaponWithContainerId(weaponContainerId);
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
weaponContainerId = value.containerId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public WeaponData SecretWeaponCluster
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return fileBelongs.findWeaponWithContainerId(clusterContainerId);
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
clusterContainerId = value.containerId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public XomString Name;
|
public XomString Name;
|
||||||
public XomString[] Worms;
|
public XomString[] Worms;
|
||||||
public int TutorialsDone;
|
public int TutorialsDone;
|
||||||
|
@ -92,8 +69,8 @@ namespace LibW4M.Data.Teams
|
||||||
this.AllMissionsDone = reader.ReadBool();
|
this.AllMissionsDone = reader.ReadBool();
|
||||||
this.Player = fileBelongs.LookupStringFromId(reader.ReadCompressedInt());
|
this.Player = fileBelongs.LookupStringFromId(reader.ReadCompressedInt());
|
||||||
|
|
||||||
this.weaponContainerId = reader.ReadCompressedInt();
|
this.SecretWeapon = fileBelongs.findWeaponWithContainerId(reader.ReadCompressedInt());
|
||||||
this.clusterContainerId = reader.ReadCompressedInt();
|
this.SecretWeaponCluster = fileBelongs.findWeaponWithContainerId(reader.ReadCompressedInt());
|
||||||
|
|
||||||
this.CustomWeapon = fileBelongs.LookupStringFromId(reader.ReadCompressedInt());
|
this.CustomWeapon = fileBelongs.LookupStringFromId(reader.ReadCompressedInt());
|
||||||
|
|
||||||
|
|
|
@ -11,4 +11,28 @@
|
||||||
<ProjectReference Include="..\LibXom\LibXom.csproj" />
|
<ProjectReference Include="..\LibXom\LibXom.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="PS2\PS2SaveResources.Designer.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>PS2SaveResources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Update="PS2\SaveResources.Designer.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>SaveResources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Update="PS2\PS2SaveResources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>PS2SaveResources.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Update="PS2\SaveResources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>SaveResources.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
using LibXom.Data;
|
||||||
|
using LibXom.Streams;
|
||||||
|
using LibXom;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using LibW4M.Data.Stats;
|
||||||
|
|
||||||
|
namespace LibW4M.PS2
|
||||||
|
{
|
||||||
|
public static class Ps2Save
|
||||||
|
{
|
||||||
|
private const int PS2_MAX_SZ = 0x20000;
|
||||||
|
|
||||||
|
public static void CreateSaveFile(W4SaveFile save, Stream output)
|
||||||
|
{
|
||||||
|
// Remove all stats ...
|
||||||
|
foreach (StatsContainerData stat in save.StatsCollective.ToArray())
|
||||||
|
save.StatsCollective.Delete(stat);
|
||||||
|
|
||||||
|
// Save changes
|
||||||
|
save.saveData();
|
||||||
|
XomWriter.WriteXom(save.OriginalXom,output);
|
||||||
|
Ps2Save.CalcAndWriteChecksum(output);
|
||||||
|
}
|
||||||
|
public static void CalcAndWriteChecksum(Stream s)
|
||||||
|
{
|
||||||
|
XomStreamReader reader = new XomStreamReader(s);
|
||||||
|
XomStreamWriter writer = new XomStreamWriter(s);
|
||||||
|
|
||||||
|
// Set size to ps2 save size.
|
||||||
|
|
||||||
|
s.SetLength(PS2_MAX_SZ);
|
||||||
|
s.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
// Calculate checksum
|
||||||
|
|
||||||
|
Int64 chk = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < (PS2_MAX_SZ - 4); i += 4)
|
||||||
|
{
|
||||||
|
int c = reader.ReadInt32();
|
||||||
|
chk = (chk + c) & UInt32.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteUInt32(Convert.ToUInt32(chk));
|
||||||
|
|
||||||
|
s.Seek(0, SeekOrigin.Begin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreatePSU(W4SaveFile save, Stream output)
|
||||||
|
{
|
||||||
|
PsuFile psuFile = new PsuFile();
|
||||||
|
psuFile.InitalizePSU("BESLES-53096W4MA");
|
||||||
|
psuFile.CreateFile("Icon1.ico", SaveResources.IconFile);
|
||||||
|
psuFile.CreateFile("icon.sys", SaveResources.IconSys);
|
||||||
|
|
||||||
|
using(MemoryStream ms = new MemoryStream())
|
||||||
|
{
|
||||||
|
CreateSaveFile(save, ms);
|
||||||
|
ms.Seek(0, SeekOrigin.Begin);
|
||||||
|
psuFile.CreateFile("BESLES-53096W4MA", ms.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
psuFile.WritePSU(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace LibW4M.PS2
|
||||||
|
{
|
||||||
|
public enum PsuEntryType : ushort
|
||||||
|
{
|
||||||
|
DIRECTORY_ENTRY = 0x8427,
|
||||||
|
FILE_ENTRY = 0x8497,
|
||||||
|
SYSTEM_ENTRY = 0xA027
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,176 @@
|
||||||
|
using LibXom.Streams;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection.PortableExecutable;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace LibW4M.PS2
|
||||||
|
{
|
||||||
|
public class PsuFile
|
||||||
|
{
|
||||||
|
public PsuFile()
|
||||||
|
{
|
||||||
|
entries = new List<PsuFileEntry>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<PsuFileEntry> entries;
|
||||||
|
|
||||||
|
|
||||||
|
public PsuFileEntry[] Entires
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return entries.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public PsuFileEntry[] Files
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
List<PsuFileEntry> tmpList = new List<PsuFileEntry>();
|
||||||
|
|
||||||
|
foreach (PsuFileEntry entry in entries)
|
||||||
|
{
|
||||||
|
if (entry.EntryType == PsuEntryType.FILE_ENTRY || entry.EntryType == PsuEntryType.SYSTEM_ENTRY)
|
||||||
|
{
|
||||||
|
tmpList.Add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmpList.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public PsuFileEntry[] Directorys
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
List<PsuFileEntry> tmpList = new List<PsuFileEntry>();
|
||||||
|
|
||||||
|
foreach (PsuFileEntry entry in entries)
|
||||||
|
{
|
||||||
|
if (entry.EntryType == PsuEntryType.DIRECTORY_ENTRY)
|
||||||
|
{
|
||||||
|
tmpList.Add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmpList.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateDirectory(string directoryName)
|
||||||
|
{
|
||||||
|
this.entries.Add(new PsuFileEntry(PsuEntryType.DIRECTORY_ENTRY, 0x00, DateTime.Now, 0, DateTime.Now, directoryName, null));
|
||||||
|
this.entries[0].directoryEntries = this.entries.Count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateFile(string fileName, byte[] data)
|
||||||
|
{
|
||||||
|
this.entries.Add(new PsuFileEntry(PsuEntryType.FILE_ENTRY, data.Length, DateTime.Now, 0, DateTime.Now, fileName, data));
|
||||||
|
this.entries[0].directoryEntries = this.entries.Count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateSystemFile(string fileName, byte[] data)
|
||||||
|
{
|
||||||
|
this.entries.Add(new PsuFileEntry(PsuEntryType.SYSTEM_ENTRY, data.Length, DateTime.Now, 0, DateTime.Now, fileName, data));
|
||||||
|
this.entries[0].directoryEntries = this.entries.Count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InitalizePSU(string titleId)
|
||||||
|
{
|
||||||
|
this.entries.Clear();
|
||||||
|
CreateDirectory(titleId);
|
||||||
|
CreateDirectory(".");
|
||||||
|
CreateDirectory("..");
|
||||||
|
}
|
||||||
|
|
||||||
|
public PsuFileEntry GetFileByName(string filename)
|
||||||
|
{
|
||||||
|
foreach(PsuFileEntry entry in this.Files)
|
||||||
|
{
|
||||||
|
if(entry.Filename.Equals(filename, StringComparison.InvariantCulture))
|
||||||
|
{
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new FileNotFoundException("Cannot find the file");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PsuFile ReadPSU(string psuFilePath)
|
||||||
|
{
|
||||||
|
PsuFile psuFile = new PsuFile();
|
||||||
|
psuFile.ReadPSU(File.OpenRead(psuFilePath));
|
||||||
|
return psuFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WritePSU(Stream psuStream)
|
||||||
|
{
|
||||||
|
using (XomStreamWriter writer = new XomStreamWriter(psuStream))
|
||||||
|
{
|
||||||
|
|
||||||
|
foreach (PsuFileEntry fileEntry in this.Entires)
|
||||||
|
{
|
||||||
|
writer.WriteUInt16((ushort)fileEntry.EntryType);
|
||||||
|
writer.Skip(0x02);
|
||||||
|
writer.WriteInt32(fileEntry.Filesize);
|
||||||
|
writer.Skip(0x01);
|
||||||
|
writer.WriteDateTime(fileEntry.CreationDate);
|
||||||
|
writer.WriteUInt16(fileEntry.Sector);
|
||||||
|
writer.Skip(0x07);
|
||||||
|
writer.WriteDateTime(fileEntry.ModifiedDate);
|
||||||
|
writer.Skip(0x20);
|
||||||
|
writer.WriteStrLen(fileEntry.Filename, 0x1C0);
|
||||||
|
|
||||||
|
if(fileEntry.FileData != Stream.Null)
|
||||||
|
{
|
||||||
|
fileEntry.FileData.Seek(0, SeekOrigin.Begin);
|
||||||
|
fileEntry.FileData.CopyTo(psuStream);
|
||||||
|
writer.WritePadding(0xFF, 0x400 - (fileEntry.Filesize % 0x400));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void ReadPSU(Stream psuStream)
|
||||||
|
{
|
||||||
|
using (XomStreamReader reader = new XomStreamReader(psuStream))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// read header
|
||||||
|
PsuEntryType type = (PsuEntryType)reader.ReadUInt16();
|
||||||
|
reader.Skip(0x02);
|
||||||
|
int size = reader.ReadInt32();
|
||||||
|
reader.Skip(0x01);
|
||||||
|
DateTime creationDate = reader.ReadDateTime();
|
||||||
|
ushort sector = reader.ReadUInt16();
|
||||||
|
reader.Skip(0x07);
|
||||||
|
DateTime modifiedDate = reader.ReadDateTime();
|
||||||
|
reader.Skip(0x20);
|
||||||
|
string filename = reader.ReadStrLen(0x1C0);
|
||||||
|
|
||||||
|
if (type == PsuEntryType.FILE_ENTRY || type == PsuEntryType.SYSTEM_ENTRY)
|
||||||
|
{
|
||||||
|
byte[] fileData = reader.ReadBytes(size);
|
||||||
|
|
||||||
|
reader.Skip(0x400 - (size % 0x400));
|
||||||
|
this.entries.Add(new PsuFileEntry(type, size, creationDate, sector, modifiedDate, filename, fileData));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.entries.Add(new PsuFileEntry(type, size, creationDate, sector, modifiedDate, filename, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (psuStream.Position < psuStream.Length);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace LibW4M.PS2
|
||||||
|
{
|
||||||
|
public class PsuFileEntry
|
||||||
|
{
|
||||||
|
|
||||||
|
internal int directoryEntries;
|
||||||
|
|
||||||
|
public Stream FileData;
|
||||||
|
public PsuEntryType EntryType;
|
||||||
|
public DateTime CreationDate;
|
||||||
|
public ushort Sector;
|
||||||
|
public DateTime ModifiedDate;
|
||||||
|
public string Filename;
|
||||||
|
public bool IsFile
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (EntryType == PsuEntryType.FILE_ENTRY || EntryType == PsuEntryType.SYSTEM_ENTRY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int Filesize
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (IsFile)
|
||||||
|
{
|
||||||
|
return Convert.ToInt32(FileData.Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return directoryEntries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (IsFile)
|
||||||
|
{
|
||||||
|
FileData.SetLength(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
directoryEntries = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public PsuFileEntry(PsuEntryType entryType, int fileSize, DateTime creationDate, ushort sector, DateTime modifiedDate, string fileName, byte[]? fileData)
|
||||||
|
{
|
||||||
|
this.EntryType = entryType;
|
||||||
|
this.directoryEntries = fileSize;
|
||||||
|
this.CreationDate = creationDate;
|
||||||
|
this.Sector = sector;
|
||||||
|
this.ModifiedDate = modifiedDate;
|
||||||
|
this.Filename = fileName;
|
||||||
|
|
||||||
|
if(fileData is null)
|
||||||
|
{
|
||||||
|
this.FileData = Stream.Null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.FileData = new MemoryStream();
|
||||||
|
this.FileData.Write(fileData, 0, fileSize);
|
||||||
|
this.FileData.Seek(0, SeekOrigin.Begin);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
Binary file not shown.
|
@ -0,0 +1,83 @@
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace LibW4M.PS2 {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
|
/// </summary>
|
||||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
|
// class via a tool like ResGen or Visual Studio.
|
||||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
|
// with the /str option, or rebuild your VS project.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class SaveResources {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal SaveResources() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LibW4M.PS2.SaveResources", typeof(SaveResources).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||||
|
/// resource lookups using this strongly typed resource class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized resource of type System.Byte[].
|
||||||
|
/// </summary>
|
||||||
|
public static byte[] IconFile {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("IconFile", resourceCulture);
|
||||||
|
return ((byte[])(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized resource of type System.Byte[].
|
||||||
|
/// </summary>
|
||||||
|
public static byte[] IconSys {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("IconSys", resourceCulture);
|
||||||
|
return ((byte[])(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,127 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||||
|
<data name="IconFile" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>Resources\Icon1.ico;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</data>
|
||||||
|
<data name="IconSys" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>Resources\icon.sys;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
|
@ -1,19 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
|
||||||
-->
|
|
||||||
<Project>
|
|
||||||
<PropertyGroup>
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Any CPU</Platform>
|
|
||||||
<PublishDir>bin\Release\net7.0\publish\win-x86\</PublishDir>
|
|
||||||
<PublishProtocol>FileSystem</PublishProtocol>
|
|
||||||
<_TargetId>Folder</_TargetId>
|
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
|
||||||
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
|
|
||||||
<SelfContained>true</SelfContained>
|
|
||||||
<PublishSingleFile>true</PublishSingleFile>
|
|
||||||
<PublishReadyToRun>true</PublishReadyToRun>
|
|
||||||
<PublishTrimmed>false</PublishTrimmed>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
|
@ -1,10 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
|
||||||
-->
|
|
||||||
<Project>
|
|
||||||
<PropertyGroup>
|
|
||||||
<History>False|2023-02-18T17:31:12.6646298Z;</History>
|
|
||||||
<LastFailureDetails />
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
|
@ -9,11 +9,13 @@ using LibW4M.Data.WeaponFactory;
|
||||||
using LibW4M.Data.WXFE;
|
using LibW4M.Data.WXFE;
|
||||||
using LibW4M.Data.WXFE.UnlockableItem;
|
using LibW4M.Data.WXFE.UnlockableItem;
|
||||||
using LibW4M.Data.X;
|
using LibW4M.Data.X;
|
||||||
|
using LibW4M.PS2;
|
||||||
using LibXom;
|
using LibXom;
|
||||||
using LibXom.Blocks;
|
using LibXom.Blocks;
|
||||||
using LibXom.Data;
|
using LibXom.Data;
|
||||||
using LibXom.Exceptions;
|
using LibXom.Exceptions;
|
||||||
using LibXom.Streams;
|
using LibXom.Streams;
|
||||||
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Xml.XPath;
|
using System.Xml.XPath;
|
||||||
|
|
||||||
|
@ -21,24 +23,31 @@ namespace LibW4M
|
||||||
{
|
{
|
||||||
public class W4SaveFile
|
public class W4SaveFile
|
||||||
{
|
{
|
||||||
public const int PS2_MAX_SZ = 0x20000;
|
|
||||||
|
|
||||||
private List<UnlockableItemData> unlockableItems;
|
private List<UnlockableItemData> unlockableItems;
|
||||||
private XomFile xomFile;
|
private XomFile xomFile;
|
||||||
|
|
||||||
public DataBank XDataBank;
|
public DataBank XDataBank;
|
||||||
|
|
||||||
|
|
||||||
public WeaponsCollective WeaponFactoryCollective;
|
public WeaponsCollective WeaponFactoryCollective;
|
||||||
public TeamsCollective TeamDataColective;
|
public TeamsCollective TeamDataColective;
|
||||||
public SchemesCollective SchemesCollective;
|
public SchemesCollective SchemesCollective;
|
||||||
public HighscoreCollective HighscoreCollective;
|
public HighscoreCollective HighscoreCollective;
|
||||||
public StatsCollective StatsCollective;
|
public StatsCollective StatsCollective;
|
||||||
public StatsCollective TeamStatsCollective;
|
public TeamStatsCollective TeamStatsCollective;
|
||||||
public InputMappingCollective InputMappingCollective;
|
public InputMappingCollective InputMappingCollective;
|
||||||
|
|
||||||
public TeamAwardsData TeamAwardsContainer;
|
public TeamAwardsData TeamAwardsContainer;
|
||||||
|
public XomString Message;
|
||||||
|
public XomString FEResourceID;
|
||||||
|
|
||||||
|
public XomFile OriginalXom
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.xomFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
public UnlockableItemData[] UnlockableItems
|
public UnlockableItemData[] UnlockableItems
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -84,7 +93,7 @@ namespace LibW4M
|
||||||
break;
|
break;
|
||||||
case "PersistStats":
|
case "PersistStats":
|
||||||
StatsCollective = new StatsCollective(this, containerResourceDetail.Value);
|
StatsCollective = new StatsCollective(this, containerResourceDetail.Value);
|
||||||
TeamStatsCollective = new StatsCollective(this, containerResourceDetail.Value);
|
TeamStatsCollective = new TeamStatsCollective(this, containerResourceDetail.Value);
|
||||||
break;
|
break;
|
||||||
case "Awards":
|
case "Awards":
|
||||||
TeamAwardsContainer = new TeamAwardsData(this, containerResourceDetail.Value);
|
TeamAwardsContainer = new TeamAwardsData(this, containerResourceDetail.Value);
|
||||||
|
@ -114,11 +123,15 @@ namespace LibW4M
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void saveData()
|
internal void saveData()
|
||||||
{
|
{
|
||||||
XDataBank.Save();
|
#if !DEBUG
|
||||||
|
xomFile.ClearAllStrings();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
XDataBank.Save();
|
||||||
WeaponFactoryCollective.Save();
|
WeaponFactoryCollective.Save();
|
||||||
|
|
||||||
// Save Teams, Highscores
|
// Save Teams, Highscores
|
||||||
|
@ -137,60 +150,44 @@ namespace LibW4M
|
||||||
foreach (UnlockableItemData unlockableItem in UnlockableItems)
|
foreach (UnlockableItemData unlockableItem in UnlockableItems)
|
||||||
unlockableItem.Save();
|
unlockableItem.Save();
|
||||||
}
|
}
|
||||||
|
public void SavePC(Stream pcSaveStream)
|
||||||
|
{
|
||||||
|
saveData();
|
||||||
|
using (MemoryStream ms = new MemoryStream())
|
||||||
|
{
|
||||||
|
XomWriter.WriteXom(xomFile, pcSaveStream);
|
||||||
|
|
||||||
|
ms.Seek(0, SeekOrigin.Begin);
|
||||||
|
ms.CopyTo(pcSaveStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SavePS2PSU(Stream ps2PsuSaveStream)
|
||||||
|
{
|
||||||
|
using (ps2PsuSaveStream)
|
||||||
|
{
|
||||||
|
Ps2Save.CreatePSU(this, ps2PsuSaveStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SavePS2(Stream ps2SaveStream)
|
||||||
|
{
|
||||||
|
using (ps2SaveStream)
|
||||||
|
{
|
||||||
|
Ps2Save.CreateSaveFile(this, ps2SaveStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
public void SavePS2(string newXom)
|
public void SavePS2(string newXom)
|
||||||
{
|
{
|
||||||
// Remove all stats ...
|
SavePS2(File.OpenWrite(newXom));
|
||||||
foreach(StatsContainerData stat in StatsCollective.ToArray())
|
|
||||||
StatsCollective.Delete(stat);
|
|
||||||
|
|
||||||
// Save changes
|
|
||||||
saveData();
|
|
||||||
|
|
||||||
using(FileStream fs = File.OpenWrite(newXom))
|
|
||||||
{
|
|
||||||
using (MemoryStream ms = new MemoryStream())
|
|
||||||
{
|
|
||||||
using (XomStreamReader reader = new XomStreamReader(ms))
|
|
||||||
{
|
|
||||||
using (XomStreamWriter writer = new XomStreamWriter(ms))
|
|
||||||
{
|
|
||||||
XomWriter.WriteXom(xomFile, ms);
|
|
||||||
|
|
||||||
// Set size to ps2 save size.
|
|
||||||
|
|
||||||
ms.SetLength(PS2_MAX_SZ);
|
|
||||||
ms.Seek(0, SeekOrigin.Begin);
|
|
||||||
|
|
||||||
// Calculate checksum
|
|
||||||
|
|
||||||
Int64 chk = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < (PS2_MAX_SZ - 4); i += 4)
|
|
||||||
{
|
|
||||||
int c = reader.ReadInt32();
|
|
||||||
chk = (chk + c) & UInt32.MaxValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
writer.WriteUInt32(Convert.ToUInt32(chk));
|
|
||||||
|
|
||||||
|
|
||||||
ms.Seek(0, SeekOrigin.Begin);
|
|
||||||
ms.CopyTo(fs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public void Save(string newXom)
|
public void SavePS2PSU(string newXom)
|
||||||
{
|
{
|
||||||
saveData();
|
SavePS2PSU(File.OpenWrite(newXom));
|
||||||
|
}
|
||||||
XomWriter.WriteXom(xomFile, newXom);
|
public void SavePC(string newXom)
|
||||||
|
{
|
||||||
|
SavePC(File.OpenWrite(newXom));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ExtractAllContainers(string path)
|
public void ExtractAllContainers(string path)
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace LibXom.Data
|
||||||
{
|
{
|
||||||
private int version;
|
private int version;
|
||||||
private int unk0;
|
private int unk0;
|
||||||
|
|
||||||
private List<XomString> xomStrings = new List<XomString>();
|
private List<XomString> xomStrings = new List<XomString>();
|
||||||
private List<XomType> xomTypes = new List<XomType>();
|
private List<XomType> xomTypes = new List<XomType>();
|
||||||
|
|
||||||
|
@ -47,14 +48,25 @@ namespace LibXom.Data
|
||||||
xomStrings[stringId] = newStr;
|
xomStrings[stringId] = newStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal int addString(XomString xStr)
|
||||||
|
{
|
||||||
|
xomStrings.Add(xStr);
|
||||||
|
return xomStrings.Count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearAllStrings()
|
||||||
|
{
|
||||||
|
xomStrings.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
public XomString AddOrGetString(string value)
|
public XomString AddOrGetString(string value)
|
||||||
{
|
{
|
||||||
XomString[] strings = XomStrings;
|
XomString[] strings = XomStrings;
|
||||||
for (int i = 0; i < strings.Length; i++)
|
for (int i = 0; i < strings.Length; i++)
|
||||||
if (strings[i].Value == value) return strings[i];
|
if (strings[i].Equals(value)) return strings[i];
|
||||||
|
|
||||||
XomString str = new XomString(this, value);
|
XomString str = new XomString(this, value);
|
||||||
xomStrings.Add(str);
|
addString(str);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +90,15 @@ namespace LibXom.Data
|
||||||
|
|
||||||
throw new XomTypeNotFoundException("Type \"" + typeName + "\" was not found in XOM.");
|
throw new XomTypeNotFoundException("Type \"" + typeName + "\" was not found in XOM.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal int calculateIdForXomStrings(XomString searchString, XomString[] stringsList)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < stringsList.Length; i++)
|
||||||
|
if (stringsList[i].Equals(searchString)) return i;
|
||||||
|
|
||||||
|
return addString(searchString);
|
||||||
|
}
|
||||||
|
|
||||||
internal int calculateIdForXomFileComponent(string searchUuid, XomFileComponent[] components)
|
internal int calculateIdForXomFileComponent(string searchUuid, XomFileComponent[] components)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < components.Length; i++)
|
for (int i = 0; i < components.Length; i++)
|
||||||
|
@ -90,11 +111,13 @@ namespace LibXom.Data
|
||||||
{
|
{
|
||||||
XomContainer[] containers = this.XomContainers;
|
XomContainer[] containers = this.XomContainers;
|
||||||
XomType[] types = this.XomTypes;
|
XomType[] types = this.XomTypes;
|
||||||
XomString[] strings = XomStrings;
|
XomString[] strings = this.XomStrings;
|
||||||
|
|
||||||
List<XomBlock> blocks = new List<XomBlock>();
|
List<XomBlock> blocks = new List<XomBlock>();
|
||||||
|
|
||||||
// add MOIK block
|
// add MOIK block
|
||||||
blocks.Add(new MoikBlock(this.version, containers.Length, types.Length));
|
blocks.Add(new MoikBlock(this.version, containers.Length, types.Length));
|
||||||
|
|
||||||
// add type blocks
|
// add type blocks
|
||||||
foreach (XomType type in types) blocks.Add(new TypeBlock(type.Containers.Length, type.Md5, type.Name));
|
foreach (XomType type in types) blocks.Add(new TypeBlock(type.Containers.Length, type.Md5, type.Name));
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace LibXom.Data
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return this.fileBelongs.calculateIdForXomFileComponent(this.uuid, fileBelongs.XomStrings) - 1;
|
return this.fileBelongs.calculateIdForXomStrings(this, fileBelongs.XomStrings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public string Value
|
public string Value
|
||||||
|
@ -34,13 +34,23 @@ namespace LibXom.Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
public override bool Equals(object? obj)
|
||||||
public void OverwriteXomString(string newValue)
|
|
||||||
{
|
{
|
||||||
this.value = newValue;
|
XomString? xStr = obj as XomString;
|
||||||
fileBelongs.updateStringById(this.Id, this);
|
if (xStr is XomString)
|
||||||
|
return this.Value.Equals(xStr.Value, StringComparison.InvariantCulture);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
public void OverwriteXomString(string newValue)
|
||||||
|
{
|
||||||
|
this.value = newValue;
|
||||||
|
fileBelongs.updateStringById(this.Id, this);
|
||||||
|
}
|
||||||
|
*/
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return this.Value;
|
return this.Value;
|
||||||
|
|
|
@ -50,7 +50,10 @@ namespace LibXom.Data
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new XomContainerNotFoundException("Could not find Xom Container with uuid: " + container.uuid + " in type: " + this.Name);
|
|
||||||
|
// maybe removed this container by mistakes; so lets just add it back
|
||||||
|
container.Type.xomContainers.Add(container);
|
||||||
|
return getContainerIndex(container);
|
||||||
}
|
}
|
||||||
public void ReplaceContainerData(XomContainer container, byte[] newData)
|
public void ReplaceContainerData(XomContainer container, byte[] newData)
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,6 +53,19 @@ namespace LibXom.Streams
|
||||||
xStream.Read(buffer, 0, amt);
|
xStream.Read(buffer, 0, amt);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DateTime ReadDateTime()
|
||||||
|
{
|
||||||
|
byte secs = ReadByte();
|
||||||
|
byte minutes = ReadByte();
|
||||||
|
byte hours = ReadByte();
|
||||||
|
byte days = ReadByte();
|
||||||
|
byte months = ReadByte();
|
||||||
|
UInt16 years = ReadUInt16();
|
||||||
|
|
||||||
|
return new DateTime(years, months, days, hours, minutes, secs);
|
||||||
|
}
|
||||||
|
|
||||||
public bool ReadBool()
|
public bool ReadBool()
|
||||||
{
|
{
|
||||||
return (ReadByte() == 0x01);
|
return (ReadByte() == 0x01);
|
||||||
|
@ -92,6 +105,16 @@ namespace LibXom.Streams
|
||||||
{
|
{
|
||||||
return BitConverter.ToSingle(ReadBytes(0x4));
|
return BitConverter.ToSingle(ReadBytes(0x4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ushort ReadUInt16()
|
||||||
|
{
|
||||||
|
return BitConverter.ToUInt16(ReadBytes(0x2));
|
||||||
|
}
|
||||||
|
public short ReadInt16()
|
||||||
|
{
|
||||||
|
return BitConverter.ToInt16(ReadBytes(0x2));
|
||||||
|
}
|
||||||
|
|
||||||
public uint ReadUInt32()
|
public uint ReadUInt32()
|
||||||
{
|
{
|
||||||
return BitConverter.ToUInt32(ReadBytes(0x4));
|
return BitConverter.ToUInt32(ReadBytes(0x4));
|
||||||
|
|
|
@ -95,6 +95,26 @@ namespace LibXom.Streams
|
||||||
WriteBytes(buffer);
|
WriteBytes(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void WriteDateTime(DateTime date)
|
||||||
|
{
|
||||||
|
WriteByte(Convert.ToByte(date.Second));
|
||||||
|
WriteByte(Convert.ToByte(date.Minute));
|
||||||
|
WriteByte(Convert.ToByte(date.Hour));
|
||||||
|
WriteByte(Convert.ToByte(date.Day));
|
||||||
|
WriteByte(Convert.ToByte(date.Month));
|
||||||
|
WriteUInt16(Convert.ToUInt16(date.Year));
|
||||||
|
}
|
||||||
|
public void WriteUInt16(ushort value)
|
||||||
|
{
|
||||||
|
byte[] buffer = BitConverter.GetBytes((ushort)value);
|
||||||
|
WriteBytes(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteInt16(short value)
|
||||||
|
{
|
||||||
|
byte[] buffer = BitConverter.GetBytes((short)value);
|
||||||
|
WriteBytes(buffer);
|
||||||
|
}
|
||||||
public void WriteUInt32(uint value)
|
public void WriteUInt32(uint value)
|
||||||
{
|
{
|
||||||
byte[] buffer = BitConverter.GetBytes((uint)value);
|
byte[] buffer = BitConverter.GetBytes((uint)value);
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace W4Gui.Components
|
||||||
{
|
{
|
||||||
int sel = lst.SelectedIndex;
|
int sel = lst.SelectedIndex;
|
||||||
if (sel >= 0)
|
if (sel >= 0)
|
||||||
lst.Items[sel] = newEntry.Text;
|
lst.Items[sel] = newEntry.Text.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void newEntry_KeyDown(object sender, KeyEventArgs e)
|
private void newEntry_KeyDown(object sender, KeyEventArgs e)
|
||||||
|
@ -93,7 +93,9 @@ namespace W4Gui.Components
|
||||||
|
|
||||||
private void lst_SelectedIndexChanged(object sender, EventArgs e)
|
private void lst_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (prevSelected >= 0)
|
if (prevSelected == lst.SelectedIndex) return;
|
||||||
|
|
||||||
|
if (prevSelected >= 0 && prevSelected < lst.Items.Count)
|
||||||
lst.Items[prevSelected] = newEntry.Text;
|
lst.Items[prevSelected] = newEntry.Text;
|
||||||
|
|
||||||
if (lst.SelectedIndex >= 0)
|
if (lst.SelectedIndex >= 0)
|
||||||
|
|
|
@ -10,6 +10,9 @@ namespace W4Gui
|
||||||
{
|
{
|
||||||
public static class DataManager
|
public static class DataManager
|
||||||
{
|
{
|
||||||
|
public static SaveType LoadedSaveType;
|
||||||
|
public static string LoadedSavePath;
|
||||||
|
|
||||||
public static bool SaveLoaded = false;
|
public static bool SaveLoaded = false;
|
||||||
public static W4SaveFile SaveFile;
|
public static W4SaveFile SaveFile;
|
||||||
public static void SaveAll()
|
public static void SaveAll()
|
||||||
|
|
|
@ -58,6 +58,7 @@ namespace W4Gui
|
||||||
this.awardPanel = new W4Gui.Tabs.AwardTab();
|
this.awardPanel = new W4Gui.Tabs.AwardTab();
|
||||||
this.variablesTab = new System.Windows.Forms.TabPage();
|
this.variablesTab = new System.Windows.Forms.TabPage();
|
||||||
this.variablesPage = new W4Gui.Tabs.VariablesTab.VariablesTabs();
|
this.variablesPage = new W4Gui.Tabs.VariablesTab.VariablesTabs();
|
||||||
|
this.saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.mainMenuStrip.SuspendLayout();
|
this.mainMenuStrip.SuspendLayout();
|
||||||
this.mainTabControl.SuspendLayout();
|
this.mainTabControl.SuspendLayout();
|
||||||
this.weaponTab.SuspendLayout();
|
this.weaponTab.SuspendLayout();
|
||||||
|
@ -87,7 +88,8 @@ namespace W4Gui
|
||||||
//
|
//
|
||||||
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
this.openToolStripMenuItem,
|
this.openToolStripMenuItem,
|
||||||
this.saveToolStripMenuItem});
|
this.saveToolStripMenuItem,
|
||||||
|
this.saveAsToolStripMenuItem});
|
||||||
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
|
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
|
||||||
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
|
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
|
||||||
this.fileToolStripMenuItem.Text = "File";
|
this.fileToolStripMenuItem.Text = "File";
|
||||||
|
@ -95,7 +97,7 @@ namespace W4Gui
|
||||||
// openToolStripMenuItem
|
// openToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.openToolStripMenuItem.Name = "openToolStripMenuItem";
|
this.openToolStripMenuItem.Name = "openToolStripMenuItem";
|
||||||
this.openToolStripMenuItem.Size = new System.Drawing.Size(103, 22);
|
this.openToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||||
this.openToolStripMenuItem.Text = "Open";
|
this.openToolStripMenuItem.Text = "Open";
|
||||||
this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click);
|
this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click);
|
||||||
//
|
//
|
||||||
|
@ -103,7 +105,7 @@ namespace W4Gui
|
||||||
//
|
//
|
||||||
this.saveToolStripMenuItem.Enabled = false;
|
this.saveToolStripMenuItem.Enabled = false;
|
||||||
this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
|
this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
|
||||||
this.saveToolStripMenuItem.Size = new System.Drawing.Size(103, 22);
|
this.saveToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||||
this.saveToolStripMenuItem.Text = "Save";
|
this.saveToolStripMenuItem.Text = "Save";
|
||||||
this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click);
|
this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click);
|
||||||
//
|
//
|
||||||
|
@ -331,6 +333,14 @@ namespace W4Gui
|
||||||
this.variablesPage.Size = new System.Drawing.Size(182, 62);
|
this.variablesPage.Size = new System.Drawing.Size(182, 62);
|
||||||
this.variablesPage.TabIndex = 0;
|
this.variablesPage.TabIndex = 0;
|
||||||
//
|
//
|
||||||
|
// saveAsToolStripMenuItem
|
||||||
|
//
|
||||||
|
this.saveAsToolStripMenuItem.Enabled = false;
|
||||||
|
this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem";
|
||||||
|
this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||||
|
this.saveAsToolStripMenuItem.Text = "Save As";
|
||||||
|
this.saveAsToolStripMenuItem.Click += new System.EventHandler(this.saveAsToolStripMenuItem_Click);
|
||||||
|
//
|
||||||
// Main
|
// Main
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||||
|
@ -389,5 +399,6 @@ namespace W4Gui
|
||||||
private TabPage awardsTab;
|
private TabPage awardsTab;
|
||||||
private AwardTab awardPanel;
|
private AwardTab awardPanel;
|
||||||
private InputEventMappingTab inputEventMappingsPanel;
|
private InputEventMappingTab inputEventMappingsPanel;
|
||||||
|
private ToolStripMenuItem saveAsToolStripMenuItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
using LibW4M;
|
using LibW4M;
|
||||||
using LibW4M.Data.WeaponFactory;
|
using LibW4M.Data.WeaponFactory;
|
||||||
|
using LibW4M.PS2;
|
||||||
using LibXom;
|
using LibXom;
|
||||||
using LibXom.Data;
|
using LibXom.Data;
|
||||||
using System;
|
using System;
|
||||||
|
@ -29,20 +30,47 @@ namespace W4Gui
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SaveType getTypeFromName(string filename)
|
||||||
|
{
|
||||||
|
switch (Path.GetExtension(filename))
|
||||||
|
{
|
||||||
|
|
||||||
|
case ".psu":
|
||||||
|
return SaveType.PS2;
|
||||||
|
case ".xom":
|
||||||
|
default:
|
||||||
|
return SaveType.PC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void openToolStripMenuItem_Click(object sender, EventArgs e)
|
private void openToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
OpenFileDialog fd = new OpenFileDialog();
|
OpenFileDialog fd = new OpenFileDialog();
|
||||||
fd.Filter = "Worms 4: Mayhem Save File|*.xom";
|
fd.Filter = "Worms 4: Mayhem Save Files|*.xom;*.psu|Worms 4: Mayhem PC Save File|*.xom|Worms 4: Mayhem PS2 Save File|*.psu";
|
||||||
fd.Title = "Open Worms 4 Save File";
|
fd.Title = "Open Worms 4 Save File";
|
||||||
if(fd.ShowDialog() == DialogResult.OK)
|
if(fd.ShowDialog() == DialogResult.OK)
|
||||||
{
|
{
|
||||||
DataManager.SaveFile = new W4SaveFile(XomReader.ReadXomFile(fd.FileName));
|
DataManager.LoadedSavePath = fd.FileName;
|
||||||
|
DataManager.LoadedSaveType = getTypeFromName(DataManager.LoadedSavePath);
|
||||||
|
|
||||||
|
switch (DataManager.LoadedSaveType)
|
||||||
|
{
|
||||||
|
case SaveType.PS2:
|
||||||
|
DataManager.SaveFile = new W4SaveFile(XomReader.ReadXomFile(PsuFile.ReadPSU(fd.FileName).GetFileByName("BESLES-53096W4MA").FileData));
|
||||||
|
break;
|
||||||
|
case SaveType.PC:
|
||||||
|
default:
|
||||||
|
DataManager.SaveFile = new W4SaveFile(XomReader.ReadXomFile(fd.FileName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
this.mainTabControl.Enabled = true;
|
this.mainTabControl.Enabled = true;
|
||||||
this.saveToolStripMenuItem.Enabled = true;
|
this.saveToolStripMenuItem.Enabled = true;
|
||||||
|
this.saveAsToolStripMenuItem.Enabled = true;
|
||||||
this.convertToolStripMenuItem.Enabled = true;
|
this.convertToolStripMenuItem.Enabled = true;
|
||||||
|
|
||||||
this.Text = defaultTitle + " [" + fd.FileName + "]";
|
this.Text = defaultTitle + " (" + DataManager.LoadedSaveType.ToString() + ") " + "[" + fd.FileName + "]";
|
||||||
|
|
||||||
DataManager.LoadAll();
|
DataManager.LoadAll();
|
||||||
}
|
}
|
||||||
|
@ -50,19 +78,22 @@ namespace W4Gui
|
||||||
|
|
||||||
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
|
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
SaveFileDialog fd = new SaveFileDialog();
|
mainTabControl.Enabled = false;
|
||||||
fd.Filter = "Worms 4: Mayhem Save File|*.xom";
|
DataManager.SaveAll();
|
||||||
fd.Title = "Save Worms 4 Save File";
|
switch (DataManager.LoadedSaveType)
|
||||||
fd.FileName = "SaveGame.xom";
|
|
||||||
if (fd.ShowDialog() == DialogResult.OK)
|
|
||||||
{
|
{
|
||||||
this.mainTabControl.Enabled = false;
|
case SaveType.PC:
|
||||||
|
DataManager.SaveFile.SavePC(DataManager.LoadedSavePath);
|
||||||
DataManager.SaveAll();
|
break;
|
||||||
DataManager.SaveFile.Save(fd.FileName);
|
case SaveType.PS2:
|
||||||
|
DataManager.SaveFile.SavePS2PSU(DataManager.LoadedSavePath);
|
||||||
this.mainTabControl.Enabled = true;
|
break;
|
||||||
|
case SaveType.XBOX:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
mainTabControl.Enabled = true;
|
||||||
|
MessageBox.Show("File saved to: " + DataManager.LoadedSavePath, "Save Complete!", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void extractAllXomContainersToolStripMenuItem_Click(object sender, EventArgs e)
|
private void extractAllXomContainersToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
|
@ -131,5 +162,33 @@ namespace W4Gui
|
||||||
this.mainTabControl.Enabled = true;
|
this.mainTabControl.Enabled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
SaveFileDialog fd = new SaveFileDialog();
|
||||||
|
fd.Filter = "Worms 4: Mayhem Save Files|*.xom;*.psu|Worms 4: Mayhem PC Save File|*.xom|Worms 4: Mayhem PS2 Single Save File|*.psu";
|
||||||
|
fd.Title = "Save Worms 4 Save File";
|
||||||
|
fd.FileName = Path.GetFileName(DataManager.LoadedSavePath);
|
||||||
|
if (fd.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
this.mainTabControl.Enabled = false;
|
||||||
|
|
||||||
|
DataManager.SaveAll();
|
||||||
|
SaveType saveType = getTypeFromName(fd.FileName);
|
||||||
|
|
||||||
|
switch (saveType)
|
||||||
|
{
|
||||||
|
case SaveType.PS2:
|
||||||
|
DataManager.SaveFile.SavePS2PSU(fd.FileName);
|
||||||
|
break;
|
||||||
|
case SaveType.PC:
|
||||||
|
DataManager.SaveFile.SavePC(fd.FileName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBox.Show("File saved to: " + fd.FileName, "Save Complete!", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
this.mainTabControl.Enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||||
-->
|
-->
|
||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<History>True|2023-02-28T20:19:31.4651141Z;True|2023-02-25T21:53:35.8769435+13:00;True|2023-02-20T23:18:32.2496478+13:00;True|2023-02-19T06:40:54.2502643+13:00;False|2023-02-16T17:57:46.9563146+13:00;True|2023-01-19T20:41:26.7371208+13:00;True|2023-01-15T17:06:35.5919106+13:00;True|2023-01-14T13:57:56.0824690+13:00;True|2023-01-11T22:22:28.8737310+13:00;True|2023-01-11T22:16:55.3469226+13:00;</History>
|
<History>True|2023-03-03T15:40:06.7859106Z;True|2023-03-01T11:45:37.3479871+13:00;True|2023-03-01T09:19:31.4651141+13:00;True|2023-02-25T21:53:35.8769435+13:00;True|2023-02-20T23:18:32.2496478+13:00;True|2023-02-19T06:40:54.2502643+13:00;False|2023-02-16T17:57:46.9563146+13:00;True|2023-01-19T20:41:26.7371208+13:00;True|2023-01-15T17:06:35.5919106+13:00;True|2023-01-14T13:57:56.0824690+13:00;True|2023-01-11T22:22:28.8737310+13:00;True|2023-01-11T22:16:55.3469226+13:00;</History>
|
||||||
<LastFailureDetails />
|
<LastFailureDetails />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace W4Gui
|
||||||
|
{
|
||||||
|
public enum SaveType
|
||||||
|
{
|
||||||
|
PC,
|
||||||
|
PS2,
|
||||||
|
XBOX
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue