public void SetUp() { const string mlName = "1ban"; var domainList = new List<string>{ "example.com" }; //var tsDir = new TsDir(); var kernel = new Kernel(); var logger = new Logger(); var manageDir = TestUtil.GetTmpDir("TestDir"); _tsMailSave = new TsMailSave();//MailSaveのモックオブジェクト var memberList = new Dat(new[] { CtrlType.TextBox, CtrlType.TextBox, CtrlType.CheckBox, CtrlType.CheckBox, CtrlType.CheckBox, CtrlType.TextBox }); memberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER1", "*****@*****.**", false, true, true, "")); //一般・読者・投稿 memberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER2", "*****@*****.**", false, true, false, ""));//一般・読者・× memberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER3", "*****@*****.**", false, false, true, ""));//一般・×・投稿 memberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "ADMIN", "*****@*****.**", true, false, true, "123"));//管理者・×・投稿 memberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "ADMIN2", "*****@*****.**", true, true, true, "456"));//管理者・読者・投稿 var docs = (from object o in Enum.GetValues(typeof(MlDocKind)) select "").ToList(); const int maxSummary = 10; const int getMax = 10; const bool autoRegistration = true; const int titleKind = 5; var mlOption = new MlOption(maxSummary, getMax, autoRegistration, titleKind, docs, manageDir, memberList); _ml = new Ml(kernel, logger, _tsMailSave, mlOption, mlName, domainList); }
public void 指定した文字列が表示対象か否かの判断() { var dat = new Dat(new[]{CtrlType.TextBox}); dat.Add(true, "AAA"); dat.Add(true, "表示"); dat.Add(true, "123"); dat.Add(true, "アイウ"); const bool isDisplay = true; var logLimit = new LogLimit(dat, isDisplay); //表示する var expected = true; Check(logLimit, "AAA", expected); Check(logLimit, "表示A", expected); Check(logLimit, "表A123", expected); Check(logLimit, "123", expected); Check(logLimit, "12アイウ", expected); //表示しない expected = false; Check(logLimit, "AA", expected); Check(logLimit, "表a示A", expected); Check(logLimit, "表A23", expected); Check(logLimit, "", expected); Check(logLimit, "12アイ", expected); Check(logLimit, null, expected); }
public static Dat.V1.Dto.Bom.Response<AuthenticationInfo> Authenticate(Guid userGuid, string api_url, bool secured, Dat.V1.Utils.Enumerations.DataExchangeFormats format) { Dat.V1.Dto.Bom.RequestOptions options = new Dat.V1.Dto.Bom.RequestOptions() { AuthenticationToken = "", ApiUrl = api_url, Data = new Dat.V1.Dto.Membership.Authentication.Request() { Manifest = new Manifest() { AuthenticationInfo = new AuthenticationInfo() { UserGuid = userGuid } } }, Asset = Constants.Asset, Service = Constants.Service, EndPoint = Constants.EndPoint, Method = Dat.V1.Utils.Enumerations.HttpVerbs.PUT, Secured = secured, RequestType = format, ResponseType = format }; switch (format) { case Dat.V1.Utils.Enumerations.DataExchangeFormats.JSON: return Dat.V1.Utils.Serialization.JSON.Serializer.Deserialize<Dat.V1.Dto.Bom.Response<AuthenticationInfo>>(Dat.V1.Dto.Bom.Request.Send(options)); default: throw new Dto.Bom.Exceptions.SerializationNotImplementedException("Format not supported."); }; }
public Dat Export() { var dat = new Dat(new CtrlType[] { CtrlType.TextBox, CtrlType.TextBox, CtrlType.TextBox, CtrlType.TextBox, CtrlType.TextBox, CtrlType.TextBox }); foreach (var o in _ar){ var str = string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", o.Name, o.MailAddress, o.IsManager, o.IsReader, o.IsContributor, Crypt.Encrypt(o.Psssword)); dat.Add(o.Enable, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", o.Name, o.MailAddress, o.IsManager, o.IsReader, o.IsContributor, Crypt.Encrypt(o.Psssword))); } return dat; }
public void AllowTest(string str, LimitKind limitKind, string target, bool isAllow) { var allow = new Dat(new[]{CtrlType.TextBox, CtrlType.Int }); var deny = new Dat(new[] { CtrlType.TextBox, CtrlType.Int }); allow = AddDat(allow, limitKind, str); var limitUrl = new LimitUrl(allow, deny); var errorStr = ""; Assert.AreEqual(limitUrl.IsAllow(target, ref errorStr), isAllow); }
public void FromRegに無効な文字列を与えるとfalseが返る(int colMax, String str) { //setUp var sut = new Dat(new CtrlType[colMax]); const bool expected = false; //exercise var actual = sut.FromReg(str); //verify Assert.That(actual, Is.EqualTo(expected)); }
public void enableEsmtpによる適用有無の確認_IpV4のみ設定(int enableEsmtp, String ipStr, bool expected) { //setUp var range = new Dat(new CtrlType[]{CtrlType.TextBox,CtrlType.TextBox}); range.Add(true, "name\t192.168.0.0/24"); var sut = new SmtpAuthRange(range, enableEsmtp, null); //exercise var actual = sut.IsHit(new Ip(ipStr)); //verify Assert.That(actual, Is.EqualTo(expected)); }
public void SetUp() { var datUser = new Dat(new CtrlType[2] { CtrlType.TextBox, CtrlType.TextBox }); datUser.Add(true, "user1\t3OuFXZzV8+iY6TC747UpCA=="); datUser.Add(true, "user2\tNKfF4/Tw/WMhHZvTilAuJQ=="); datUser.Add(true, "user3\tXXX"); _conf = new Conf(); _conf.Add("user", datUser); _mailBox = new MailBox(new Logger(), datUser, "c:\\tmp2\\bjd5\\Pop3Server\\mailbox"); }
public void 許可リストだけの場合(int order, bool isAllow) { //setUp var allowList = new Dat(new CtrlType[] { CtrlType.TextBox }); allowList.Add(true, "192.168.0.0/24"); var sut = new Relay(allowList, null, order, null); var expected = isAllow; //exercise var actual = sut.IsAllow(new Ip("192.168.0.1")); //verify Assert.That(actual, Is.EqualTo(expected)); }
//dat 制限文字列 //isDisplay ヒットした場合の動作(表示/非表示) public LogLimit(Dat dat, bool isDisplay) { _isDisplay = isDisplay; var tmp = new List<string>(); if (dat != null){ foreach (var o in dat){ if (o.Enable){ //有効なデータだけを対象にする tmp.Add(o.StrList[0]); } } } _limitStr = tmp.ToArray(); }
public void FromRegで初期化してtoRegで取り出す(int colMax, String str) { //setUp var ctrlTypeList = new CtrlType[colMax]; for (var i = 0; i < colMax; i++) { ctrlTypeList[i] = CtrlType.Int; } var sut = new Dat(new CtrlType[colMax]); var expected = str; sut.FromReg(str); //exercise var actual = sut.ToReg(false); //verify Assert.That(actual, Is.EqualTo(expected)); }
public void SetUp() { //var kernel = new Kernel(null,null,null,null); //var logger = new Logger(kernel,"",false,null); //参加者 var dat = new Dat(new[] { CtrlType.TextBox, CtrlType.TextBox, CtrlType.CheckBox, CtrlType.CheckBox, CtrlType.CheckBox, CtrlType.TextBox }); bool manager = false; dat.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER1", "*****@*****.**", manager, true, true, "")); //読者・投稿 dat.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER2", "*****@*****.**", manager, true, false, ""));//読者 × dat.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER3", "*****@*****.**", manager, false, true, ""));//× 投稿 manager = true;//管理者 dat.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "ADMIN", "*****@*****.**", manager, false, true, "123"));//× 投稿 _mlUserList = new MlUserList(dat); }
public void enableNum_0で_のみを許可する_を検証する(string aclStr, string ipStr, AclKind expected) { //setUp int enableNum = 0; //enableNum=0 のみを許可する Dat dat = new Dat(new CtrlType[] { CtrlType.TextBox, CtrlType.AddressV4 }); if (!dat.Add(true, string.Format("NAME\t{0}", aclStr))) { Assert.Fail("このエラーが発生したら、テストの実装に問題がある"); } var ip = TestUtil.CreateIp(ipStr); AclList sut = new AclList(dat, enableNum, new Logger()); //exercise AclKind actual = sut.Check(ip); //verify Assert.That(actual, Is.EqualTo(expected)); }
public void Appendによるヘッダの追加() { //setUp var appned = new Dat(new CtrlType[] { CtrlType.TextBox, CtrlType.TextBox }); appned.Add(true, "tag2\tzzz"); var sut = new ChangeHeader(null, appned); var mail = new Mail(); var expected = "zzz"; //exercise sut.Exec(mail, new Logger()); var actual = mail.GetHeader("tag2"); //varify Assert.That(actual, Is.EqualTo(expected)); }
//public Lease(Logger logger, string fileName, Ip startIp, Ip endIp, int leaseTime, Dat2 macAcl) { public Lease(string fileName, Ip startIp, Ip endIp, int leaseTime, Dat macAcl) { //this.logger = logger; this.fileName = fileName; this.leaseTime = leaseTime; uint start = startIp.AddrV4; uint end = endIp.AddrV4; int count = 2048;//�ő�ێ��� for (uint i = start; i <= end && count > 0; i++) { Ip ip = new Ip(i); ar.Add(new OneLease(ip));//MAC�w��Ȃ� count--; } foreach (var o in macAcl) { if (o.Enable) {//�L���ȃf�[�^������Ώۂɂ��� string macStr = o.StrList[0];//MAC�A�h���X(99-99-99-99-99-99) Mac mac = new Mac(macStr); Ip ip = new Ip(o.StrList[1]);//IP�A�h���X if (ip.ToString() == "255.255.255.255") { ar.Add(new OneLease(ip, mac));//MAC�w�肠��őS���lj� } else { // ��{�ݒ�͈̔͂̃e�[�u������� bool find = false; for (int i = 0; i < ar.Count; i++) { if (ar[i].Ip == ip) { ar[i] = new OneLease(ip, mac);//MAC�w�肠��ɕύX find = true; break; } } if (!find) { // ��{�ݒ�͈̔͊O�̏ꍇ ar.Add(new OneLease(ip, mac));//MAC�w�肠��Ƃ��Ēlj� } } } } // ���[�X���f�[�^�̓ǂݍ��� Read(); }
public void Relpaceによるヘッダの置き換え() { //setUp var replace = new Dat(new CtrlType[]{CtrlType.TextBox, CtrlType.TextBox}); replace.Add(true, "ABC\tXYZ"); var sut = new ChangeHeader(replace, null); var mail = new Mail(); mail.AddHeader("tag1", "ABC123"); mail.AddHeader("tag2", "DEF123"); mail.AddHeader("tag3", "GHI123"); var expected = "tag1: XYZ123\r\n"; //exercise sut.Exec(mail, new Logger()); var actual = Encoding.ASCII.GetString(mail.GetBytes()).Substring(0, 14); //varify Assert.That(actual, Is.EqualTo(expected)); }
public void Relpaceによるヘッダの置き換え2() { //setUp var replace = new Dat(new CtrlType[] { CtrlType.TextBox, CtrlType.TextBox }); replace.Add(true, "ABC\tBBB"); var sut = new ChangeHeader(replace, null); var mail = new Mail(); mail.AddHeader("tag1", "ABC123"); mail.AddHeader("tag2", "DEF123"); mail.AddHeader("tag3", "GHI123"); var expected = "BBB123"; //exercise sut.Exec(mail, new Logger()); var actual = mail.GetHeader("tag1"); //varify Assert.That(actual, Is.EqualTo(expected)); }
public void 許可リスト無し_のみ禁止する_Allow() { //setUp const int port = 9988; const int enableAcl = 1; //指定したアドレスからのアクセスのみを禁止する var acl = new Dat(new CtrlType[0]); //許可リストなし var sut = StartServer(port, enableAcl, acl); var cl = StartClient(port); var expected = 1; // Allow //exercise var actual = sut.Count(); //verify Assert.That(actual, Is.EqualTo(expected)); //tearDown cl.Close(); sut.Stop(); sut.Dispose(); }
readonly string _wpadUrl; //WPAD #endregion Fields #region Constructors //�R���X�g���N�^ public Server(Kernel kernel, Conf conf,OneBind oneBind) : base(kernel, conf, oneBind) { //�I�v�V�����̓ǂݍ��� _maskIp = (Ip)Conf.Get("maskIp"); _gwIp = (Ip)Conf.Get("gwIp"); _dnsIp0 = (Ip)Conf.Get("dnsIp0"); _dnsIp1 = (Ip)Conf.Get("dnsIp1"); _leaseTime = (int)Conf.Get("leaseTime"); if (_leaseTime <= 0) _leaseTime = 86400; if ((bool)Conf.Get("useWpad")) { _wpadUrl = (string)Conf.Get("wpadUrl"); } //DB���� string fileName = string.Format("{0}\\lease.db", kernel.ProgDir()); var startIp = (Ip)Conf.Get("startIp"); var endIp = (Ip)Conf.Get("endIp"); _macAcl = (Dat)Conf.Get("macAcl"); //�ݒ肪�����ꍇ�́A���Dat������ if (_macAcl == null){ _macAcl = new Dat(new CtrlType[]{CtrlType.TextBox,CtrlType.AddressV4, CtrlType.TextBox}); } //Ver5.6.8 //�J�������u���O�i�\����)�v�𑝂₵�����Ƃɂ��݊����ێ� if (_macAcl.Count > 0) { foreach (OneDat t in _macAcl){ if (t.StrList.Count == 2) { t.StrList.Add(string.Format("host_{0}",t.StrList[1])); } } } _lease = new Lease(fileName, startIp, endIp, _leaseTime, _macAcl); //�T�[�o�A�h���X�̏����� _serverAddress = Define.ServerAddress(); }
public MlOption(Kernel kernel,OneOption op) { var maxSummary = (int)op.GetValue("maxSummary"); var maxGet = (int)op.GetValue("maxGet"); var autoRegistration = (bool)op.GetValue("autoRegistration");//自動登録 var titleKind = (int)op.GetValue("title"); var docs = new List<string>(); foreach (MlDocKind docKind in Enum.GetValues(typeof(MlDocKind))) { var buf = (string)op.GetValue(docKind.ToString().ToLower() + "Document"); if (buf.Length < 2 || buf[buf.Length - 2] != '\r' || buf[buf.Length - 1] != '\n'){ buf = buf + "\r\n"; } docs.Add(buf); } var manageDir = (string)op.GetValue("manageDir"); //Ver6.0.1 manageDir = kernel.ReplaceOptionEnv(manageDir); //Ver6.0.0で間違えたフォルダの修復 if (Directory.Exists("%ExecutablePath%") && Directory.Exists("%ExecutablePath%\\ml")) { try{ var path = Path.GetFullPath("%ExecutablePath%"); var dir = Path.GetDirectoryName(path); if (dir != null){ Directory.Move(path + "\\ml", dir + "\\ml"); Directory.Delete(path); } } catch (Exception){ ; } } var memberList = (Dat)op.GetValue("memberList"); if (memberList == null){ memberList = new Dat(new[] { CtrlType.TextBox, CtrlType.TextBox, CtrlType.CheckBox, CtrlType.CheckBox, CtrlType.CheckBox, CtrlType.TextBox }); } Init(maxSummary, maxGet, autoRegistration, titleKind, docs, manageDir, memberList); }
public static Dat.V1.Dto.Bom.Response<User> Select_ByEmailAddress(string emailAddress, string authToken, bool secured, string api_url, Dat.V1.Utils.Enumerations.DataExchangeFormats format) { Dat.V1.Dto.Bom.RequestOptions options = new Dat.V1.Dto.Bom.RequestOptions() { AuthenticationToken = authToken, ApiUrl = api_url, Parameters = emailAddress, Asset = Dat.V1.Dto.Membership.Constants.Asset, Service = Membership.Constants.Service, EndPoint = Constants.EndPoint, Secured = secured, Method = Dat.V1.Utils.Enumerations.HttpVerbs.GET, RequestType = format, ResponseType = format }; switch (format) { case Dat.V1.Utils.Enumerations.DataExchangeFormats.JSON: return Dat.V1.Utils.Serialization.JSON.Serializer.Deserialize<Dat.V1.Dto.Bom.Response<User>>(Dat.V1.Dto.Bom.Request.Send(options)); default: throw new Dto.Bom.Exceptions.SerializationNotImplementedException("Format not supported."); }; }
public MailBox(Logger logger,Dat datUser,String dir) { Status = true; //��������� false�̏ꍇ�́A�������Ɏ��s���Ă���̂Ŏg�p�ł��Ȃ� _log = new Log(logger); //MailBox��z�u����t�H���_ Dir = dir; try{ Directory.CreateDirectory(Dir); } catch(Exception){ } if (!Directory.Exists(Dir)){ _log.Set(LogKind.Error, null, 9000029, string.Format("dir=")); Status = false; Dir = null; return; //�ȍ~�̏�������������Ȃ� } //���[�U���X�g�̏����� Init(datUser); }
public void 許可リスト有り_のみ許可する_Allow() { //setUp const int port = 9987; const int enableAcl = 0; //指定したアドレスからのアクセスのみを許可する var acl = new Dat(new[]{CtrlType.TextBox, CtrlType.TextBox}); //許可リストあり acl.Add(true, "NAME\t127.0.0.1"); var sut = StartServer(port, enableAcl, acl); var cl = StartClient(port); var expected = 1; // Allow //exercise var actual = sut.Count(); //verify Assert.That(actual, Is.EqualTo(expected)); //tearDown cl.Close(); sut.Stop(); sut.Dispose(); }
public void SetUp() { var tsDir = new TsDir(); _tsOption = new TsOption(tsDir); _tsOption.Set("FOLDER", "MailBox", "dir", string.Format("{0}\\MailBox", tsDir.Src)); //user1,user2,user3 _tsOption.Set("DAT", "MailBox", "user", "user1\tpass\buser2\tpass\buser3\tpass"); var kernel = new Kernel(null, null, null, null); var logger = new Logger(kernel, "LOG", false, null); var manageDir = tsDir.Src + "\\TestDir"; //MailQueue _mailQueue = new MailQueue(tsDir.Src + "\\MailQueue"); var oneOption = kernel.ListOption.Get("MailBox"); _mailBox = new MailBox(kernel, oneOption); var mailSave = new MailSave(kernel, _mailBox, logger, _mailQueue, "", _domainList);//モック var memberList = new Dat(); memberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER1", "*****@*****.**", false, true, true, "")); //一般・読者・投稿 memberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER2", "*****@*****.**", false, true, false, ""));//一般・読者・× memberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER3", "*****@*****.**", false, false, true, ""));//一般・×・投稿 //memberList.Add(false, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER6" , "*****@*****.**" , false, false, true, ""));//一般・×・投稿 (Disable) //memberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "ADMIN" , "*****@*****.**" , true, false, true, "123"));//管理者・×・投稿 //memberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "ADMIN2", "*****@*****.**", true, true, true, "456"));//管理者・読者・投稿 //memberList.Add(false, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "ADMIN3", "*****@*****.**", true, true, true, "789"));//管理者・読者・投稿 (Disable) var docs = (from object o in Enum.GetValues(typeof(MLDocKind)) select "").ToList(); const int maxSummary = 10; const int getMax = 10; const bool autoRegistration = true; const int titleKind = 1; var mlOption = new MlOption(maxSummary, getMax, autoRegistration, titleKind, docs, manageDir, memberList); _ml = new Ml(kernel, logger, mailSave, mlOption, _mlName, _domainList); }
/// <summary> /// Imports an MTRL file /// </summary> /// <param name="xivMtrl">The XivMtrl containing the mtrl data</param> /// <param name="item">The item whos mtrl is being imported</param> /// <param name="source">The source/application that is writing to the dat.</param> /// <returns>The new offset</returns> public int ImportMtrl(XivMtrl xivMtrl, IItem item, string source) { var mtrlBytes = new List <byte>(); mtrlBytes.AddRange(BitConverter.GetBytes(xivMtrl.Signature)); mtrlBytes.AddRange(BitConverter.GetBytes(xivMtrl.FileSize)); mtrlBytes.AddRange(BitConverter.GetBytes(xivMtrl.ColorSetDataSize)); mtrlBytes.AddRange(BitConverter.GetBytes(xivMtrl.MaterialDataSize)); mtrlBytes.AddRange(BitConverter.GetBytes(xivMtrl.TexturePathsDataSize)); mtrlBytes.Add(xivMtrl.TextureCount); mtrlBytes.Add(xivMtrl.MapCount); mtrlBytes.Add(xivMtrl.ColorSetCount); mtrlBytes.Add(xivMtrl.UnknownDataSize); for (int i = 0; i < xivMtrl.TexturePathOffsetList.Count; i++) { mtrlBytes.AddRange(BitConverter.GetBytes((short)xivMtrl.TexturePathOffsetList[i])); mtrlBytes.AddRange(BitConverter.GetBytes((short)xivMtrl.TexturePathUnknownList[i])); } for (int i = 0; i < xivMtrl.MapPathOffsetList.Count; i++) { mtrlBytes.AddRange(BitConverter.GetBytes((short)xivMtrl.MapPathOffsetList[i])); mtrlBytes.AddRange(BitConverter.GetBytes((short)xivMtrl.MapPathUnknownList[i])); } for (int i = 0; i < xivMtrl.ColorSetPathOffsetList.Count; i++) { mtrlBytes.AddRange(BitConverter.GetBytes((short)xivMtrl.ColorSetPathOffsetList[i])); mtrlBytes.AddRange(BitConverter.GetBytes((short)xivMtrl.ColorSetPathUnknownList[i])); } var pathStringList = new List <byte>(); foreach (var texPathString in xivMtrl.TexturePathList) { pathStringList.AddRange(Encoding.UTF8.GetBytes(texPathString)); pathStringList.Add(0); } foreach (var mapPathString in xivMtrl.MapPathList) { pathStringList.AddRange(Encoding.UTF8.GetBytes(mapPathString)); pathStringList.Add(0); } foreach (var colorSetPathString in xivMtrl.ColorSetPathList) { pathStringList.AddRange(Encoding.UTF8.GetBytes(colorSetPathString)); pathStringList.Add(0); } pathStringList.AddRange(Encoding.UTF8.GetBytes(xivMtrl.Shader)); pathStringList.Add(0); var paddingSize = xivMtrl.MaterialDataSize - pathStringList.Count; pathStringList.AddRange(new byte[paddingSize]); mtrlBytes.AddRange(pathStringList); mtrlBytes.AddRange(xivMtrl.Unknown2); foreach (var colorSetHalf in xivMtrl.ColorSetData) { mtrlBytes.AddRange(BitConverter.GetBytes(colorSetHalf.RawValue)); } if (xivMtrl.ColorSetDataSize == 544) { mtrlBytes.AddRange(xivMtrl.ColorSetExtraData); } mtrlBytes.AddRange(BitConverter.GetBytes(xivMtrl.AdditionalDataSize)); mtrlBytes.AddRange(BitConverter.GetBytes(xivMtrl.DataStruct1Count)); mtrlBytes.AddRange(BitConverter.GetBytes(xivMtrl.DataStruct2Count)); mtrlBytes.AddRange(BitConverter.GetBytes(xivMtrl.ParameterStructCount)); mtrlBytes.AddRange(BitConverter.GetBytes(xivMtrl.ShaderNumber)); mtrlBytes.AddRange(BitConverter.GetBytes(xivMtrl.Unknown3)); foreach (var dataStruct1 in xivMtrl.DataStruct1List) { mtrlBytes.AddRange(BitConverter.GetBytes(dataStruct1.ID)); mtrlBytes.AddRange(BitConverter.GetBytes(dataStruct1.Unknown1)); } foreach (var dataStruct2 in xivMtrl.DataStruct2List) { mtrlBytes.AddRange(BitConverter.GetBytes(dataStruct2.ID)); mtrlBytes.AddRange(BitConverter.GetBytes(dataStruct2.Offset)); mtrlBytes.AddRange(BitConverter.GetBytes(dataStruct2.Size)); } foreach (var parameterStruct in xivMtrl.ParameterStructList) { mtrlBytes.AddRange(BitConverter.GetBytes(parameterStruct.ID)); mtrlBytes.AddRange(BitConverter.GetBytes(parameterStruct.Unknown1)); mtrlBytes.AddRange(BitConverter.GetBytes(parameterStruct.Unknown2)); mtrlBytes.AddRange(BitConverter.GetBytes(parameterStruct.TextureIndex)); } mtrlBytes.AddRange(xivMtrl.AdditionalData); var dat = new Dat(_gameDirectory); return(dat.ImportType2Data(mtrlBytes.ToArray(), item.Name, xivMtrl.MTRLPath, item.Category, source)); }
public void Given_an_empty_dat_Then_count_returns_correct_value() { Dat df = new Dat(); Assert.AreEqual(0, df.Count, "Incorrect count was returned"); }
/// <summary> /// Gets the MTRL data for the given offset and path /// </summary> /// <param name="mtrlOffset">The offset to the mtrl in the dat file</param> /// <param name="mtrlPath">The full internal game path for the mtrl</param> /// <returns>XivMtrl containing all the mtrl data</returns> public XivMtrl GetMtrlData(int mtrlOffset, string mtrlPath, int dxVersion) { var dat = new Dat(_gameDirectory); var index = new Index(_gameDirectory); // Get uncompressed mtrl data var mtrlData = dat.GetType2Data(mtrlOffset, _dataFile); XivMtrl xivMtrl; using (var br = new BinaryReader(new MemoryStream(mtrlData))) { xivMtrl = new XivMtrl { Signature = br.ReadInt32(), FileSize = br.ReadInt16(), ColorSetDataSize = br.ReadUInt16(), MaterialDataSize = br.ReadUInt16(), TexturePathsDataSize = br.ReadUInt16(), TextureCount = br.ReadByte(), MapCount = br.ReadByte(), ColorSetCount = br.ReadByte(), UnknownDataSize = br.ReadByte(), TextureTypePathList = new List <TexTypePath>(), MTRLPath = mtrlPath }; var pathSizeList = new List <int>(); // get the texture path offsets xivMtrl.TexturePathOffsetList = new List <int>(xivMtrl.TextureCount); xivMtrl.TexturePathUnknownList = new List <short>(xivMtrl.TextureCount); for (var i = 0; i < xivMtrl.TextureCount; i++) { xivMtrl.TexturePathOffsetList.Add(br.ReadInt16()); xivMtrl.TexturePathUnknownList.Add(br.ReadInt16()); // add the size of the paths if (i > 0) { pathSizeList.Add(xivMtrl.TexturePathOffsetList[i] - xivMtrl.TexturePathOffsetList[i - 1]); } } // get the map path offsets xivMtrl.MapPathOffsetList = new List <int>(xivMtrl.MapCount); xivMtrl.MapPathUnknownList = new List <short>(xivMtrl.MapCount); for (var i = 0; i < xivMtrl.MapCount; i++) { xivMtrl.MapPathOffsetList.Add(br.ReadInt16()); xivMtrl.MapPathUnknownList.Add(br.ReadInt16()); // add the size of the paths if (i > 0) { pathSizeList.Add(xivMtrl.MapPathOffsetList[i] - xivMtrl.MapPathOffsetList[i - 1]); } else { pathSizeList.Add(xivMtrl.MapPathOffsetList[i] - xivMtrl.TexturePathOffsetList[xivMtrl.TextureCount - 1]); } } // get the color set offsets xivMtrl.ColorSetPathOffsetList = new List <int>(xivMtrl.ColorSetCount); xivMtrl.ColorSetPathUnknownList = new List <short>(xivMtrl.ColorSetCount); for (var i = 0; i < xivMtrl.ColorSetCount; i++) { xivMtrl.ColorSetPathOffsetList.Add(br.ReadInt16()); xivMtrl.ColorSetPathUnknownList.Add(br.ReadInt16()); // add the size of the paths if (i > 0) { pathSizeList.Add(xivMtrl.ColorSetPathOffsetList[i] - xivMtrl.ColorSetPathOffsetList[i - 1]); } else { pathSizeList.Add(xivMtrl.ColorSetPathOffsetList[i] - xivMtrl.MapPathOffsetList[xivMtrl.MapCount - 1]); } } pathSizeList.Add(xivMtrl.TexturePathsDataSize - xivMtrl.ColorSetPathOffsetList[xivMtrl.ColorSetCount - 1]); var count = 0; // get the texture path strings xivMtrl.TexturePathList = new List <string>(xivMtrl.TextureCount); for (var i = 0; i < xivMtrl.TextureCount; i++) { var texturePath = Encoding.UTF8.GetString(br.ReadBytes(pathSizeList[count])).Replace("\0", ""); var dx11FileName = Path.GetFileName(texturePath).Insert(0, "--"); if (index.FileExists(HashGenerator.GetHash(dx11FileName), HashGenerator.GetHash(Path.GetDirectoryName(texturePath).Replace("\\", "/")), _dataFile)) { texturePath = texturePath.Insert(texturePath.LastIndexOf("/") + 1, "--"); } xivMtrl.TexturePathList.Add(texturePath); count++; } // add the textures to the TextureTypePathList xivMtrl.TextureTypePathList.AddRange(GetTexNames(xivMtrl.TexturePathList, _dataFile)); // get the map path strings xivMtrl.MapPathList = new List <string>(xivMtrl.MapCount); for (var i = 0; i < xivMtrl.MapCount; i++) { xivMtrl.MapPathList.Add(Encoding.UTF8.GetString(br.ReadBytes(pathSizeList[count])).Replace("\0", "")); count++; } // get the color set path strings xivMtrl.ColorSetPathList = new List <string>(xivMtrl.ColorSetCount); for (var i = 0; i < xivMtrl.ColorSetCount; i++) { xivMtrl.ColorSetPathList.Add(Encoding.UTF8.GetString(br.ReadBytes(pathSizeList[count])).Replace("\0", "")); count++; } // If the mtrl file contains a color set, add it to the TextureTypePathList if (xivMtrl.ColorSetDataSize > 0) { var ttp = new TexTypePath { Path = mtrlPath, Type = XivTexType.ColorSet, DataFile = _dataFile }; xivMtrl.TextureTypePathList.Add(ttp); } var shaderPathSize = xivMtrl.MaterialDataSize - xivMtrl.TexturePathsDataSize; xivMtrl.Shader = Encoding.UTF8.GetString(br.ReadBytes(shaderPathSize)).Replace("\0", ""); xivMtrl.Unknown2 = br.ReadBytes(xivMtrl.UnknownDataSize); if (xivMtrl.ColorSetDataSize > 0) { // Color Data is always 512 (6 x 14 = 64 x 8bpp = 512) var colorDataSize = 512; xivMtrl.ColorSetData = new List <Half>(); for (var i = 0; i < colorDataSize / 2; i++) { xivMtrl.ColorSetData.Add(new Half(br.ReadUInt16())); } // If the color set is 544 in length, it has an extra 32 bytes at the end if (xivMtrl.ColorSetDataSize == 544) { xivMtrl.ColorSetExtraData = br.ReadBytes(32); } } xivMtrl.AdditionalDataSize = br.ReadUInt16(); xivMtrl.DataStruct1Count = br.ReadUInt16(); xivMtrl.DataStruct2Count = br.ReadUInt16(); xivMtrl.ParameterStructCount = br.ReadUInt16(); xivMtrl.ShaderNumber = br.ReadUInt16(); xivMtrl.Unknown3 = br.ReadUInt16(); xivMtrl.DataStruct1List = new List <DataStruct1>(xivMtrl.DataStruct1Count); for (var i = 0; i < xivMtrl.DataStruct1Count; i++) { xivMtrl.DataStruct1List.Add(new DataStruct1 { ID = br.ReadUInt32(), Unknown1 = br.ReadUInt32() }); } xivMtrl.DataStruct2List = new List <DataStruct2>(xivMtrl.DataStruct2Count); for (var i = 0; i < xivMtrl.DataStruct2Count; i++) { xivMtrl.DataStruct2List.Add(new DataStruct2 { ID = br.ReadUInt32(), Offset = br.ReadInt16(), Size = br.ReadInt16() }); } xivMtrl.ParameterStructList = new List <ParameterStruct>(xivMtrl.ParameterStructCount); for (var i = 0; i < xivMtrl.ParameterStructCount; i++) { xivMtrl.ParameterStructList.Add(new ParameterStruct { ID = br.ReadUInt32(), Unknown1 = br.ReadInt16(), Unknown2 = br.ReadInt16(), TextureIndex = br.ReadUInt32() }); } xivMtrl.AdditionalData = br.ReadBytes(xivMtrl.AdditionalDataSize); } return(xivMtrl); }
/// <summary> /// Saves a set of IMC entries to file. /// </summary> /// <param name="path"></param> /// <param name="entries"></param> /// <returns></returns> internal async Task SaveEntries(string path, string slot, List <XivImc> entries, IItem referenceItem = null, IndexFile cachedIndexFile = null, ModList cachedModList = null) { var dat = new Dat(_gameDirectory); var index = new Index(_gameDirectory); var exists = await index.FileExists(path); FullImcInfo info; if (exists) { info = await GetFullImcInfo(path, cachedIndexFile, cachedModList); } else { var ri = XivDependencyGraph.ExtractRootInfo(path); if (ri.SecondaryType == null) { info = new FullImcInfo() { DefaultSubset = new List <XivImc>() { new XivImc(), new XivImc(), new XivImc(), new XivImc(), new XivImc() }, SubsetList = new List <List <XivImc> >(), TypeIdentifier = ImcType.Set }; } else { info = new FullImcInfo() { DefaultSubset = new List <XivImc>() { new XivImc() }, SubsetList = new List <List <XivImc> >(), TypeIdentifier = ImcType.NonSet }; } } for (int i = 0; i < entries.Count; i++) { XivImc e; if (i >= info.SubsetCount + 1) { e = new XivImc(); } else { e = info.GetEntry(i, slot); } e.Mask = entries[i].Mask; e.Decal = entries[i].Decal; e.Vfx = entries[i].Vfx; e.Animation = entries[i].Animation; e.MaterialSet = entries[i].MaterialSet; if (i >= info.SubsetCount + 1) { info.SetEntry(e, i, slot, true); } } // Save the modified info. await SaveFullImcInfo(info, path, Constants.InternalModSourceName, referenceItem, cachedIndexFile, cachedModList); }
/// <summary> /// Gets the texture paths from the uld file /// </summary> /// <returns>List of texture paths from the uld file</returns> public async Task <List <string> > GetTexFromUld() { var uldLock = new object(); var hashedFolder = HashGenerator.GetHash("ui/uld"); var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var uldStringList = new HashSet <string>(); var uldOffsetList = await index.GetAllFileOffsetsInFolder(hashedFolder, XivDataFile._06_Ui); await Task.Run(() => Parallel.ForEach(uldOffsetList, (offset) => { byte[] uldData; try { uldData = dat.GetType2Data(offset, XivDataFile._06_Ui).Result; } catch (Exception ex) { Debug.WriteLine($"Error at offset: {offset}"); Debug.WriteLine($"Message: {ex.Message}"); return; } if (uldData.Length < 10) { return; } using (var br = new BinaryReader(new MemoryStream(uldData))) { var signature = br.ReadInt32(); if (signature != 1751411829) { return; } br.ReadBytes(56); int pathCount = br.ReadByte(); br.ReadBytes(7); for (var i = 0; i < pathCount; i++) { var pathNum = br.ReadInt32(); while (pathNum != i + 1) { pathNum = br.ReadInt32(); } var path = Encoding.UTF8.GetString(br.ReadBytes(48)).Replace("\0", ""); path = new string(path.Where(c => !char.IsControl(c)).ToArray()); if (path.Length <= 2 || !path.Contains("uld")) { continue; } var uldPath = path.Substring(0, path.LastIndexOf(".", StringComparison.Ordinal) + 4); lock (uldLock) { uldStringList.Add(uldPath); } } } })); return(uldStringList.ToList()); }
/// <summary> /// Checks the mods for any problems /// </summary> private void CheckMods() { var modListDirectory = new DirectoryInfo(Path.Combine(_gameDirectory.Parent.Parent.FullName, XivStrings.ModlistFilePath)); var modList = JsonConvert.DeserializeObject <ModList>(File.ReadAllText(modListDirectory.FullName)); var dat = new Dat(_gameDirectory); if (modList.modCount > 0) { foreach (var mod in modList.Mods) { if (mod.name.Equals(string.Empty)) { continue; } var fileName = Path.GetFileName(mod.fullPath); var tabs = ""; if (fileName.Length < 21 && fileName.Length > 12) { tabs = "\t"; } else if (fileName.Length < 12) { tabs = "\t\t"; } AddText($"\t{fileName}{tabs}", textColor); if (mod.data.originalOffset == 0) { AddText("\t\u2716\n", "Red"); AddText("\tOriginal Offset was 0, you will be unable to revert to original, consider starting over. \n", "Red"); } else if (mod.data.modOffset == 0) { AddText("\t\u2716\n", "Red"); AddText("\tMod Offset was 0, Disable from File > Modlist and reimport.\n", "Red"); } else { AddText("\t\u2714", "Green"); } var fileType = 0; try { fileType = dat.GetFileType(mod.data.modOffset, XivDataFiles.GetXivDataFile(mod.datFile)); } catch (Exception ex) { AddText("\t\u2716\n", "Red"); AddText($"\tError: {ex.Message}\n", "Red"); } if (fileType != 2 && fileType != 3 && fileType != 4) { AddText("\t\u2716\n", "Red"); AddText($"\tFound unknown file type ( {fileType} ) offset is most likely corrupt.\n", "Red"); } else { AddText("\t\u2714\n", "Green"); } } } else { AddText("\tNo entries found in modlist.\n", "Orange"); } }
/// <summary> /// Gets the full IMC information for a given item /// </summary> /// <param name="item"></param> /// <param name="useSecondary">Determines if the SecondaryModelInfo should be used instead.(XivGear only)</param> /// <returns>The ImcData data</returns> public async Task <FullImcInfo> GetFullImcInfo(string path, IndexFile index = null, ModList modlist = null) { if (index == null) { var _index = new Index(_gameDirectory); index = await _index.GetIndexFile(IOUtil.GetDataFileFromPath(path), false, true); } var dat = new Dat(_gameDirectory); var imcOffset = index.Get8xDataOffset(path); if (imcOffset == 0) { throw new InvalidDataException($"Could not find offset for {path}"); } var imcByteData = await dat.GetType2Data(imcOffset, IOUtil.GetDataFileFromPath(path)); return(await Task.Run(() => { using (var br = new BinaryReader(new MemoryStream(imcByteData))) { var subsetCount = br.ReadInt16(); var identifier = br.ReadInt16(); var imcData = new FullImcInfo() { TypeIdentifier = (ImcType)identifier, DefaultSubset = new List <XivImc>(), SubsetList = new List <List <XivImc> >(subsetCount) }; //weapons and monsters do not have variant sets if (imcData.TypeIdentifier == ImcType.NonSet) { // This type uses the first short for both Variant and VFX. byte variant = br.ReadByte(); byte unknown = br.ReadByte(); ushort mask = br.ReadUInt16(); byte vfx = br.ReadByte(); byte anim = br.ReadByte(); imcData.DefaultSubset.Add(new XivImc { MaterialSet = variant, Decal = unknown, Mask = mask, Vfx = variant, Animation = anim }); for (var i = 0; i < subsetCount; i++) { variant = br.ReadByte(); unknown = br.ReadByte(); mask = br.ReadUInt16(); vfx = br.ReadByte(); anim = br.ReadByte(); var newEntry = new XivImc { MaterialSet = variant, Decal = unknown, Mask = mask, Vfx = vfx, Animation = anim }; var subset = new List <XivImc>() { newEntry }; imcData.SubsetList.Add(subset); } } else if (imcData.TypeIdentifier == ImcType.Set) { // Identifier used by Equipment. imcData.DefaultSubset = new List <XivImc>() { new XivImc { MaterialSet = br.ReadByte(), Decal = br.ReadByte(), Mask = br.ReadUInt16(), Vfx = br.ReadByte(), Animation = br.ReadByte() }, new XivImc { MaterialSet = br.ReadByte(), Decal = br.ReadByte(), Mask = br.ReadUInt16(), Vfx = br.ReadByte(), Animation = br.ReadByte() }, new XivImc { MaterialSet = br.ReadByte(), Decal = br.ReadByte(), Mask = br.ReadUInt16(), Vfx = br.ReadByte(), Animation = br.ReadByte() }, new XivImc { MaterialSet = br.ReadByte(), Decal = br.ReadByte(), Mask = br.ReadUInt16(), Vfx = br.ReadByte(), Animation = br.ReadByte() }, new XivImc { MaterialSet = br.ReadByte(), Decal = br.ReadByte(), Mask = br.ReadUInt16(), Vfx = br.ReadByte(), Animation = br.ReadByte() }, }; for (var i = 0; i < subsetCount; i++) { // gets the data for each slot in the current variant set var imcGear = new List <XivImc>() { new XivImc { MaterialSet = br.ReadByte(), Decal = br.ReadByte(), Mask = br.ReadUInt16(), Vfx = br.ReadByte(), Animation = br.ReadByte() }, new XivImc { MaterialSet = br.ReadByte(), Decal = br.ReadByte(), Mask = br.ReadUInt16(), Vfx = br.ReadByte(), Animation = br.ReadByte() }, new XivImc { MaterialSet = br.ReadByte(), Decal = br.ReadByte(), Mask = br.ReadUInt16(), Vfx = br.ReadByte(), Animation = br.ReadByte() }, new XivImc { MaterialSet = br.ReadByte(), Decal = br.ReadByte(), Mask = br.ReadUInt16(), Vfx = br.ReadByte(), Animation = br.ReadByte() }, new XivImc { MaterialSet = br.ReadByte(), Decal = br.ReadByte(), Mask = br.ReadUInt16(), Vfx = br.ReadByte(), Animation = br.ReadByte() }, }; imcData.SubsetList.Add(imcGear); } } else { throw new NotSupportedException("Unknown IMC Type Identifier. (Please report this item in the TexTools Discord #bug_reports channel.)"); } return imcData; } })); }
private async Task CreateAdvanced() { string modPackPath = Path.Combine(Properties.Settings.Default.ModPack_Directory, $"{ViewModel.Name}.ttmp2"); if (File.Exists(modPackPath)) { DialogResult overwriteDialogResult = FlexibleMessageBox.Show(new Wpf32Window(this), UIMessages.ModPackOverwriteMessage, UIMessages.OverwriteTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (overwriteDialogResult != System.Windows.Forms.DialogResult.Yes) { return; } } await LockUi(UIStrings.Creating_Modpack, null, null); try { TTMP texToolsModPack = new TTMP(new DirectoryInfo(Settings.Default.ModPack_Directory), XivStrings.TexTools); var index = new Index(XivCache.GameInfo.GameDirectory); var dat = new Dat(XivCache.GameInfo.GameDirectory); var modding = new Modding(XivCache.GameInfo.GameDirectory); var ModList = modding.GetModList(); var wizardData = new ModPackData() { Name = ViewModel.Name, Author = ViewModel.Author, Version = ViewModel.Version, Description = ViewModel.Description, Url = ViewModel.Url, ModPackPages = new List <ModPackData.ModPackPage>() }; var page = new ModPackData.ModPackPage() { PageIndex = 1, ModGroups = new List <ModGroup>() }; wizardData.ModPackPages.Add(page); foreach (var e in ViewModel.Entries) { var item = e.Item; var files = e.AllFiles; var group = new ModGroup() { GroupName = item.Name, SelectionType = "Multi", OptionList = new List <ModOption>() }; page.ModGroups.Add(group); var option = new ModOption { GroupName = group.GroupName, IsChecked = true, Name = GetNiceLevelName(e.Level, true, true), Description = "Item: " + item.Name + "\nInclusion Level: " + GetNiceLevelName(e.Level) + "\nPrimary Files:" + e.MainFiles.Count + "\nTotal Files:" + e.AllFiles.Count, SelectionType = "Multi", }; group.OptionList.Add(option); foreach (var file in e.AllFiles) { var exists = await index.FileExists(file); // This is a funny case where in order to create the modpack we actually have to write a default meta entry to the dats first. // If we had the right functions we could just load and serialize the data, but we don't atm. if (!exists && Path.GetExtension(file) == ".meta") { var meta = await ItemMetadata.GetMetadata(file); await ItemMetadata.SaveMetadata(meta, XivStrings.TexTools); } var offset = await index.GetDataOffset(file); var dataFile = IOUtil.GetDataFileFromPath(file); var compressedSize = await dat.GetCompressedFileSize(offset, dataFile); var modEntry = ModList.Mods.FirstOrDefault(x => x.fullPath == file); var modded = modEntry != null && modEntry.enabled == true; var fData = new ModData { Name = e.Item.Name, Category = e.Item.SecondaryCategory, FullPath = file, IsDefault = !modded, ModDataBytes = dat.GetRawData(offset, dataFile, compressedSize) }; option.Mods.Add(file, fData); } } // Okay modpack is now created internally, just need to save it. var progressIndicator = new Progress <double>(ReportProgressAdv); await texToolsModPack.CreateWizardModPack(wizardData, progressIndicator, true); FlexibleMessageBox.Show(new Wpf32Window(this), "Modpack Created Successfully.", "Modpack Created", MessageBoxButtons.OK, MessageBoxIcon.Information); await UnlockUi(this); DialogResult = true; } catch (Exception ex) { FlexibleMessageBox.Show(new Wpf32Window(this), "An Error occured while creating the modpack.\n\n" + ex.Message, "Modpack Creation Error", MessageBoxButtons.OK, MessageBoxIcon.Error); await UnlockUi(this); } }
/// <summary> /// Checks for older modlist /// </summary> private async void CheckForOldModList() { var oldModListFileDirectory = new DirectoryInfo( $"{Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)}/TexTools/TexTools.modlist"); if (File.Exists(oldModListFileDirectory.FullName)) { var modListContent = File.ReadAllLines(oldModListFileDirectory.FullName); if (modListContent.Length > 0) { if (FlexibleMessageBox.Show(_win32Window, UIMessages.OldTexToolsFoundMessage, UIMessages.OldModListFoundTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { var modding = new Modding(_gameDirectory); var dat = new Dat(_gameDirectory); var error = false; if (_index.IsIndexLocked(XivDataFile._0A_Exd)) { FlexibleMessageBox.Show(_win32Window, UIMessages.ModListIndexLockedErrorMessage, UIMessages.ModListDisableFailedTitle, MessageBoxButtons.OK, MessageBoxIcon.Warning); error = true; } else { try { await modding.DisableOldModList(oldModListFileDirectory); } catch (Exception ex) { error = true; FlexibleMessageBox.Show(_win32Window, string.Format(UIMessages.OldModListDisableFailedMessage, ex.Message), UIMessages.PreviousVersionErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); } } if (!error) { File.Delete(oldModListFileDirectory.FullName); // Delete modded dat files foreach (var xivDataFile in (XivDataFile[])Enum.GetValues(typeof(XivDataFile))) { var datFiles = await dat.GetModdedDatList(xivDataFile); foreach (var datFile in datFiles) { File.Delete(datFile); } } } else { System.Windows.Application.Current.Shutdown(); } } else { System.Windows.Application.Current.Shutdown(); } } } }
MlOption CreateMlOption() { const int maxSummary = 20; const int maxGet = 20; const bool autoRegistration = true; //自動登録 var tsDir = new TsDir(); const int titleKind = 1; var memberList = new Dat(); memberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER1", "*****@*****.**", false, true, true, "")); //読者・投稿 memberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER2", "*****@*****.**", false, true, false, ""));//読者 × memberList.Add(false, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER6", "*****@*****.**", false, false, true, ""));//× 投稿 (Disable) memberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER3", "*****@*****.**", false, false, true, ""));//× 投稿 memberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "ADMIN", "*****@*****.**", true, false, true, "123"));//× 投稿 memberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "ADMIN2", "*****@*****.**", true, true, true, "456"));//読者 投稿 memberList.Add(false, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "ADMIN3", "*****@*****.**", true, true, true, "789"));//読者 投稿 (Disable) return new MlOption(null,maxSummary, maxGet, autoRegistration,titleKind,Docs,tsDir.Src + "\\TestDir",memberList); }
public MapParser(Dat datContextIn, Dat datContextOut) { DatContextInput = datContextIn; DatContextOutput = datContextOut; Map = new MapFragment(); }
/// <summary> /// Event handler for the start over menu item clicked /// </summary> private async void Menu_StartOver_Click(object sender, RoutedEventArgs e) { var gameDirectory = new DirectoryInfo(Settings.Default.FFXIV_Directory); var index = new Index(gameDirectory); var outdated = false; if (index.IsIndexLocked(XivDataFile._0A_Exd)) { FlexibleMessageBox.Show(UIMessages.IndexLockedErrorMessage, UIMessages.IndexLockedErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } var result = FlexibleMessageBox.Show(UIMessages.StartOverMessage, UIMessages.StartOverTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Information); if (result == System.Windows.Forms.DialogResult.Yes) { var indexBackupsDirectory = new DirectoryInfo(Settings.Default.Backup_Directory); if (!Directory.Exists(indexBackupsDirectory.FullName)) { FlexibleMessageBox.Show(UIMessages.BackupFolderAccessErrorMessage, UIMessages.IndexBackupsErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } var filesToCheck = new XivDataFile[] { XivDataFile._01_Bgcommon, XivDataFile._04_Chara, XivDataFile._06_Ui }; var problemChecker = new ProblemChecker(gameDirectory); foreach (var xivDataFile in filesToCheck) { var backupFile = new DirectoryInfo($"{indexBackupsDirectory.FullName}\\{xivDataFile.GetDataFileName()}.win32.index"); if (!File.Exists(backupFile.FullName)) { continue; } var outdatedCheck = await problemChecker.CheckForOutdatedBackups(xivDataFile, indexBackupsDirectory); if (!outdatedCheck) { FlexibleMessageBox.Show(UIMessages.OutdatedBackupsErrorMessage, UIMessages.IndexBackupsErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); outdated = true; } } await Task.Run(async() => { var modding = new Modding(gameDirectory); await modding.DeleteAllFilesAddedByTexTools(); var dat = new Dat(gameDirectory); var modListDirectory = new DirectoryInfo(Path.Combine(gameDirectory.Parent.Parent.FullName, XivStrings.ModlistFilePath)); var backupFiles = Directory.GetFiles(indexBackupsDirectory.FullName); // Make sure backups exist if (backupFiles.Length == 0) { FlexibleMessageBox.Show(string.Format(UIMessages.NoBackupsFoundErrorMessage, indexBackupsDirectory.FullName), UIMessages.BackupFilesMissingTitle, MessageBoxButtons.OK, MessageBoxIcon.Warning); // Toggle off all mods await modding.ToggleAllMods(false); } else if (outdated) { // Toggle off all mods await modding.ToggleAllMods(false); } else { // Copy backups to ffxiv folder foreach (var backupFile in backupFiles) { if (backupFile.Contains(".win32.index")) { File.Copy(backupFile, $"{gameDirectory}/{Path.GetFileName(backupFile)}", true); } } } // Delete modded dat files foreach (var xivDataFile in (XivDataFile[])Enum.GetValues(typeof(XivDataFile))) { var datFiles = await dat.GetModdedDatList(xivDataFile); foreach (var datFile in datFiles) { File.Delete(datFile); } if (datFiles.Count > 0) { await problemChecker.RepairIndexDatCounts(xivDataFile); } } // Delete mod list File.Delete(modListDirectory.FullName); modding.CreateModlist(); }); UpdateViews(ItemTreeView.SelectedItem as Category); await this.ShowMessageAsync(UIMessages.StartOverCompleteTitle, UIMessages.StartOverCompleteMessage); } }
/// <summary> /// Reads and parses the ExData file /// </summary> /// <remarks> /// This reads the data at each index of the exd file /// It then places the data in a dictionary with format [index, raw data] /// </remarks> /// <param name="exFile"></param> /// <returns>A dictionary containing the Index and Raw Data of the ex file</returns> public Dictionary <int, byte[]> ReadExData(XivEx exFile) { var exdOffsetList = new List <int>(); var exdDataDictionary = new Dictionary <int, byte[]>(); ReadExHeader(exFile); var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var language = "_" + _langCode; // Some Ex files are universal and do not have a language code if (LanguageList.Count <= 1) { language = ""; } // Each page is a new exd file // A good example is item_[page]_[language].exd // item_0_en.exd, item_500_en.exd, item_1000_en.exd, etc. foreach (var page in PageList) { var exdFile = exFile + "_" + page + language + ExdExtension; var exdFolderHash = HashGenerator.GetHash("exd"); var exdFileHash = HashGenerator.GetHash(exdFile); exdOffsetList.Add(index.GetDataOffset(exdFolderHash, exdFileHash, XivDataFile._0A_Exd)); } foreach (var offset in exdOffsetList) { var exData = dat.GetType2Data(offset, XivDataFile._0A_Exd); // Big Endian Byte Order using (var br = new BinaryReaderBE(new MemoryStream(exData))) { br.ReadBytes(8); var offsetTableSize = br.ReadInt32(); for (var i = 0; i < offsetTableSize; i += 8) { br.BaseStream.Seek(i + 32, SeekOrigin.Begin); var entryNum = br.ReadInt32(); var entryOffset = br.ReadInt32(); br.BaseStream.Seek(entryOffset, SeekOrigin.Begin); var entrySize = br.ReadInt32(); br.ReadBytes(2); exdDataDictionary.Add(entryNum, br.ReadBytes(entrySize)); } } } return(exdDataDictionary); }
/// <summary> /// Performs post-patch modlist corrections and validation, prompting user also to generate backups after a successful completion. /// </summary> /// <returns></returns> public async Task DoPostPatchCleanup() { FlexibleMessageBox.Show(_mainWindow.Win32Window, UIMessages.PatchDetectedMessage, "Post Patch Cleanup Starting", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); MainWindow.MakeHighlander(); var resetLumina = false; await _mainWindow.LockUi("Performing Post-Patch Maintenence", "This may take a few minutes if you have many mods installed.", this); var gi = XivCache.GameInfo; if (XivCache.GameInfo.UseLumina) { resetLumina = true; XivCache.SetGameInfo(gi.GameDirectory, gi.GameLanguage, gi.DxMode, false, false, gi.LuminaDirectory, gi.UseLumina); } var workerStatus = XivCache.CacheWorkerEnabled; if (workerStatus) { // Stop the cache worker if it's running. XivCache.CacheWorkerEnabled = false; } try { var modding = new Modding(_gameDirectory); var _index = new Index(_gameDirectory); var _dat = new Dat(_gameDirectory); var validTypes = new List <int>() { 2, 3, 4 }; // We have to do a few things here. // 1. Save a list of what mods were enabled. // 2. Go through and validate everything that says it is enabled actually is enabled, or mark it as disabled and update its original index offset if it is not. // 3. Prompt the user for either a full disable and backup creation, or a restore to normal state (re-enable anything that was enabled before but is not now) var modList = modding.GetModList(); Dictionary <XivDataFile, IndexFile> indexFiles = new Dictionary <XivDataFile, IndexFile>(); // Cache our currently enabled stuff. List <Mod> enabledMods = modList.Mods.Where(x => x.enabled == true).ToList(); var toRemove = new List <Mod>(); foreach (var mod in modList.Mods) { if (!String.IsNullOrEmpty(mod.fullPath)) { var df = IOUtil.GetDataFileFromPath(mod.fullPath); if (!indexFiles.ContainsKey(df)) { indexFiles[df] = await _index.GetIndexFile(df); } var index1Value = indexFiles[df].Get8xDataOffset(mod.fullPath); var index2Value = indexFiles[df].Get8xDataOffsetIndex2(mod.fullPath); var oldOriginalOffset = mod.data.originalOffset; var modOffset = mod.data.modOffset; // In any event where an offset does not match either of our saved offsets, we must assume this is a new // default file offset for post-patch. if (index1Value != oldOriginalOffset && index1Value != modOffset && index1Value != 0) { // Index 1 value is our new base offset. var type = _dat.GetFileType(index1Value, df); // Make sure the file it's trying to point to is actually valid. if (validTypes.Contains(type)) { mod.data.originalOffset = index1Value; mod.enabled = false; } else { // Oh dear. The new index is f****d. Is the old Index Ok? type = _dat.GetFileType(oldOriginalOffset, df); if (validTypes.Contains(type) && oldOriginalOffset != 0) { // Old index is fine, so keep using that. // But mark the index value as invalid, so that we stomp on the index value after this. index1Value = -1; mod.enabled = false; } else { // Okay... Maybe the new Index2 Value? if (index2Value != 0) { type = _dat.GetFileType(index2Value, df); if (validTypes.Contains(type)) { // Set the index 1 value to invalid so that the if later down the chain stomps the index1 value. index1Value = -1; mod.data.originalOffset = index2Value; mod.enabled = false; } else { // We be f****d. throw new Exception("Unable to determine working original offset for file:" + mod.fullPath); } } else { // We be f****d. throw new Exception("Unable to determine working original offset for file:" + mod.fullPath); } } } } else if (index2Value != oldOriginalOffset && index2Value != modOffset && index2Value != 0) { // Our Index 1 was normal, but our Index 2 is changed to an unknown value. // If the index 2 points to a valid file, we must assume that this new file // is our new base data offset. var type = _dat.GetFileType(index2Value, df); if (validTypes.Contains(type) && index2Value != 0) { mod.data.originalOffset = index2Value; mod.enabled = false; } else { // Oh dear. The new index is f****d. Is the old Index Ok? type = _dat.GetFileType(oldOriginalOffset, df); if (validTypes.Contains(type) && oldOriginalOffset != 0) { // Old index is fine, so keep using that, but set the index2 value to invalid to ensure we // stomp on the current broken index value. index2Value = -1; } else { // We be f****d. throw new Exception("Unable to determine working original offset for file:" + mod.fullPath); } } } // Indexes don't match. This can occur if SE adds something to index2 that didn't exist in index2 before. if (index1Value != index2Value && index2Value != 0) { // We should never actually get to this state for file-addition mods. If we do, uh.. I guess correct the indexes and yolo? // ( Only way we get here is if SE added a new file at the same name as a file the user had created via modding, in which case, it's technically no longer a file addition mod ) indexFiles[df].SetDataOffset(mod.fullPath, mod.data.originalOffset); index1Value = mod.data.originalOffset; index2Value = mod.data.originalOffset; mod.enabled = false; } // Set it to the corrected state. if (index1Value == mod.data.modOffset) { mod.enabled = true; } else { mod.enabled = false; } // Perform a basic file type check on our results. var fileType = _dat.GetFileType(mod.data.modOffset, IOUtil.GetDataFileFromPath(mod.fullPath)); var originalFileType = _dat.GetFileType(mod.data.modOffset, IOUtil.GetDataFileFromPath(mod.fullPath)); if (!validTypes.Contains(fileType) || mod.data.modOffset == 0) { // Mod data is busted. Fun. toRemove.Add(mod); } if ((!validTypes.Contains(originalFileType)) || mod.data.originalOffset == 0) { if (mod.IsCustomFile()) { // Okay, in this case this is recoverable as the mod is a custom addition anyways, so we can just delete it. if (!toRemove.Contains(mod)) { toRemove.Add(mod); } } else { // Update ended up with us unable to find a working offset. Double fun. throw new Exception("Unable to determine working offset for file:" + mod.fullPath); } } } // Okay, this mod is now represented in the modlist in it's actual post-patch index state. var datNum = (int)((mod.data.modOffset / 8) & 0x0F) / 2; var dat = XivDataFiles.GetXivDataFile(mod.datFile); var originalDats = await _dat.GetUnmoddedDatList(dat); var datPath = $"{dat.GetDataFileName()}{Dat.DatExtension}{datNum}"; // Test for SE Dat file rollover. if (originalDats.Contains(datPath)) { // Shit. This means that the dat file where this mod lived got eaten by SE. We have to destroy the modlist entry at this point. toRemove.Add(mod); } } // Save any index changes we made. foreach (var dkv in indexFiles) { await _index.SaveIndexFile(dkv.Value); } // The modlist is now saved in its current index-represented post patch state. modding.SaveModList(modList); // We now need to clear out any mods that are irreparably f****d, and clear out all of our // internal data files so we can rebuild them later. var internalFiles = modList.Mods.Where(x => x.IsInternal()); toRemove.AddRange(internalFiles); if (toRemove.Count > 0) { var removedString = ""; // Soft-Disable all metadata mods, since we're going to purge their internal file entries. var metadata = modList.Mods.Where(x => x.fullPath.EndsWith(".meta") || x.fullPath.EndsWith(".rgsp")); foreach (var mod in metadata) { var df = IOUtil.GetDataFileFromPath(mod.fullPath); await modding.ToggleModUnsafe(false, mod, true, false, indexFiles[df], modList); } foreach (var mod in toRemove) { if (mod.data.modOffset == 0 || mod.data.originalOffset == 0) { if (mod.data.originalOffset == 0 && mod.enabled) { // This is awkward. We have a mod whose data got bashed, but has no valid original offset to restore. // So the indexes here are f****d if we do, f****d if we don't. throw new Exception("Patch-Broken file has no valid index to restore. Clean Index Restoration required."); } modList.Mods.Remove(mod); enabledMods.Remove(mod); removedString += mod.fullPath + "\n"; } else { if (mod.enabled) { var df = IOUtil.GetDataFileFromPath(mod.fullPath); await modding.ToggleModUnsafe(false, mod, true, false, indexFiles[df], modList); } modList.Mods.Remove(mod); // Since we're deleting this entry entirely, we can't leave it in the other cached list either to get re-enabled later. enabledMods.Remove(mod); if (!mod.IsInternal()) { removedString += mod.fullPath + "\n"; } } } // Save the index files and modlist again now that we've removed all the invalid entries. foreach (var dkv in indexFiles) { await _index.SaveIndexFile(dkv.Value); } modding.SaveModList(modList); // Show the user a message if we purged any real files. if (toRemove.Any(x => !String.IsNullOrEmpty(x.fullPath) && !x.IsInternal())) { var text = String.Format(UIMessages.PatchDestroyedFiles, removedString); FlexibleMessageBox.Show(_mainWindow.Win32Window, text, "Destroyed Files Notification", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1); } } // Always create clean index backups after this process is completed. _mainWindow.LockProgress.Report("Disabling Mods..."); await modding.ToggleAllMods(false); _mainWindow.LockProgress.Report("Creating Index Backups..."); var pc = new ProblemChecker(_gameDirectory); DirectoryInfo backupDir; try { Directory.CreateDirectory(Settings.Default.Backup_Directory); backupDir = new DirectoryInfo(Settings.Default.Backup_Directory); } catch { throw new Exception("Unable to create index backups.\nThe Index Backup directory is invalid or inaccessible: " + Settings.Default.Backup_Directory); } await pc.BackupIndexFiles(backupDir); // Now restore the modlist enable/disable state back to how the user had it before. _mainWindow.LockProgress.Report("Re-Enabling mods..."); // Re-enable things. await modding.ToggleMods(true, enabledMods.Select(x => x.fullPath)); FlexibleMessageBox.Show(_mainWindow.Win32Window, UIMessages.PostPatchComplete, "Post-Patch Process Complete", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); } catch (Exception Ex) { // Show the user the error, then let them go about their business of fixing things. FlexibleMessageBox.Show(_mainWindow.Win32Window, String.Format(UIMessages.PostPatchError, Ex.Message), "Post-Patch Failure", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); } finally { if (resetLumina) { // Reset lumina mode back to on if we disabled it to perform update checks. XivCache.SetGameInfo(gi.GameDirectory, gi.GameLanguage, gi.DxMode, true, false, gi.LuminaDirectory, true); } XivCache.CacheWorkerEnabled = workerStatus; await _mainWindow.UnlockUi(this); } }
/// <summary> /// Converts a DDS file into a TEX file then returns the raw data /// </summary> /// <param name="xivTex">The texture data</param> /// <param name="item">The item who's texture we are importing</param> /// <param name="ddsFileDirectory">The directory of the dds file being imported</param> /// <returns>The offset to the new imported data</returns> public byte[] DDStoTexData(XivTex xivTex, IItem item, DirectoryInfo ddsFileDirectory) { var offset = 0; var dat = new Dat(_gameDirectory); if (File.Exists(ddsFileDirectory.FullName)) { using (var br = new BinaryReader(File.OpenRead(ddsFileDirectory.FullName))) { br.BaseStream.Seek(12, SeekOrigin.Begin); var newHeight = br.ReadInt32(); var newWidth = br.ReadInt32(); br.ReadBytes(8); var newMipCount = br.ReadInt32(); if (newHeight % 2 != 0 || newWidth % 2 != 0) { throw new Exception("Resolution must be a multiple of 2"); } br.BaseStream.Seek(80, SeekOrigin.Begin); var textureFlags = br.ReadInt32(); var texType = br.ReadInt32(); XivTexFormat textureType; if (DDSType.ContainsKey(texType)) { textureType = DDSType[texType]; } else { throw new Exception($"DDS Type ({texType}) not recognized."); } switch (textureFlags) { case 2 when textureType == XivTexFormat.A8R8G8B8: textureType = XivTexFormat.A8; break; case 65 when textureType == XivTexFormat.A8R8G8B8: var bpp = br.ReadInt32(); if (bpp == 32) { textureType = XivTexFormat.A8R8G8B8; } else { var red = br.ReadInt32(); switch (red) { case 31744: textureType = XivTexFormat.A1R5G5B5; break; case 3840: textureType = XivTexFormat.A4R4G4B4; break; } } break; } if (textureType == xivTex.TextureFormat) { var uncompressedLength = (int)new FileInfo(ddsFileDirectory.FullName).Length - 128; var newTex = new List <byte>(); if (!xivTex.TextureTypeAndPath.Path.Contains(".atex")) { var DDSInfo = DDS.ReadDDS(br, xivTex, newWidth, newHeight, newMipCount); newTex.AddRange(dat.MakeType4DatHeader(xivTex, DDSInfo.mipPartOffsets, DDSInfo.mipPartCounts, uncompressedLength, newMipCount, newWidth, newHeight)); newTex.AddRange(MakeTextureInfoHeader(xivTex, newWidth, newHeight, newMipCount)); newTex.AddRange(DDSInfo.compressedDDS); return(newTex.ToArray()); } else { br.BaseStream.Seek(128, SeekOrigin.Begin); newTex.AddRange(MakeTextureInfoHeader(xivTex, newWidth, newHeight, newMipCount)); newTex.AddRange(br.ReadBytes(uncompressedLength)); return(newTex.ToArray()); } } else { throw new Exception($"Incorrect file type. Expected: {xivTex.TextureFormat} Given: {textureType}"); } } } else { throw new IOException($"Could not find file: {ddsFileDirectory.FullName}"); } }
public async Task <bool> Save() { if (_metadata == null) { return(false); } var success = false; try { await MainWindow.GetMainWindow().LockUi("Updating Metadata"); await ItemMetadata.SaveMetadata(_metadata, XivStrings.TexTools); var _mdl = new Mdl(XivCache.GameInfo.GameDirectory, IOUtil.GetDataFileFromPath(_metadata.Root.Info.GetRootFile())); foreach (var kv in _metadata.EqdpEntries) { if (kv.Value.bit1 == false) { continue; } if (_original.EqdpEntries[kv.Key].bit1 == true) { continue; } // Here we have a new race, we need to create a model for it. await _mdl.AddRacialModel(_metadata.Root.Info.PrimaryId, _metadata.Root.Info.Slot, kv.Key, XivStrings.TexTools); } if (_metadata.ImcEntries.Count > 0) { var _dat = new Dat(XivCache.GameInfo.GameDirectory); var originalMaterialSetMax = _original.ImcEntries.Select(x => x.MaterialSet).Max(); var newMaterialSetMax = _metadata.ImcEntries.Select(x => x.MaterialSet).Max(); if (newMaterialSetMax > originalMaterialSetMax) { // We have new materials to add. // First find the base files to copy. (Just always copy from set 1 for simplicity) var copySource = await _metadata.Root.GetMaterialFiles(1); var item = _metadata.Root.GetFirstItem(); for (int i = originalMaterialSetMax + 1; i <= newMaterialSetMax; i++) { foreach (var material in copySource) { var dest = material.Replace("v0001", "v" + i.ToString().PadLeft(4, '0')); await _dat.CopyFile(material, dest, XivStrings.TexTools, false, item); } } } } success = true; } catch (Exception Ex) { Helpers.FlexibleMessageBox.Show("An Error occured while saving the Metadata: \n" + Ex.Message, "Metadata Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error, System.Windows.Forms.MessageBoxDefaultButton.Button1); } finally { await MainWindow.GetMainWindow().UnlockUi(); } if (success) { var mw = MainWindow.GetMainWindow(); mw.ReloadItem(); } return(success); }
/// <summary> /// Gets the full IMC information for a given item /// </summary> /// <param name="item"></param> /// <param name="modelInfo"></param> /// <returns>The ImcData data</returns> public ImcData GetFullImcInfo(IItemModel item, XivModelInfo modelInfo) { var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var itemType = ItemType.GetItemType(item); var imcPath = GetImcPath(modelInfo, itemType); var imcOffset = index.GetDataOffset(HashGenerator.GetHash(imcPath.Folder), HashGenerator.GetHash(imcPath.File), _dataFile); if (imcOffset == 0) { throw new Exception($"Could not find offest for {imcPath.Folder}/{imcPath.File}"); } var imcByteData = dat.GetType2Data(imcOffset, _dataFile); using (var br = new BinaryReader(new MemoryStream(imcByteData))) { var imcData = new ImcData() { VariantCount = br.ReadInt16(), Unknown = br.ReadInt16(), GearVariantList = new List <VariantSet>() }; //weapons and monsters do not have variant sets if (itemType == XivItemType.weapon || itemType == XivItemType.monster) { imcData.OtherVariantList = new List <XivImc>(); for (var i = 0; i < imcData.VariantCount; i++) { imcData.OtherVariantList.Add(new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }); } } else { imcData.GearVariantList = new List <VariantSet>(); for (var i = 0; i < imcData.VariantCount + 1; i++) { // gets the data for each slot in the current variant set var imcGear = new VariantSet { Slot1 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot2 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot3 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot4 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot5 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, }; imcData.GearVariantList.Add(imcGear); } } return(imcData); } }
public void 重複する2つのリソースの追加() { //setUp var dat = new Dat(new CtrlType[5]); dat.Add(true, "0\twww\talias\t192.168.0.1\t10"); dat.Add(true, "0\twww\talias\t192.168.0.1\t10"); var sut = new RrDb(null, null, dat, "example.com", true); //(1)a www.example.com. 192.168.0.1 //(2)ptr 1.0.168.192.in.addr.ptr www.example.com. var expected = 2; //exercise var actual = RrDbTest.Size(sut); //verify Assert.That(actual, Is.EqualTo(expected)); }
public Task PerformStartOver(DirectoryInfo backupsDirectory, IProgress <string> progress = null, XivLanguage language = XivLanguage.None) { return(Task.Run(async() => { var modding = new Modding(_gameDirectory); var backupsRestored = false; // Stop the cache worker since we're blowing up the entire index file and db anyways. // The cache rebuild will start it up again after the cache is rebuilt. XivCache.CacheWorkerEnabled = false; try { // Try restoring the indexes FIRST. backupsRestored = await RestoreBackups(backupsDirectory); progress?.Report("Restoring index file backups..."); if (!backupsRestored) { throw new Exception("Start Over Failed: Index backups missing/outdated."); } } catch (Exception ex) { try { // If the index restore failed, try just disabling. await modding.DeleteAllFilesAddedByTexTools(); await modding.ToggleAllMods(false); progress?.Report("Index restore failed, attempting to delete all mods instead..."); } catch { throw new Exception("Start Over Failed: Index Backups Invalid and Unable to Disable all mods."); } } finally { progress?.Report("Deleting modded dat files..."); var dat = new Dat(_gameDirectory); // Delete modded dat files foreach (var xivDataFile in (XivDataFile[])Enum.GetValues(typeof(XivDataFile))) { var datFiles = await dat.GetModdedDatList(xivDataFile); foreach (var datFile in datFiles) { File.Delete(datFile); } if (datFiles.Count > 0) { await RepairIndexDatCounts(xivDataFile); } } progress?.Report("Cleaning up mod list..."); var modListDirectory = new DirectoryInfo(Path.Combine(_gameDirectory.Parent.Parent.FullName, XivStrings.ModlistFilePath)); // Delete mod list File.Delete(modListDirectory.FullName); modding.CreateModlist(); progress?.Report("Rebuilding Cache..."); await Task.Run(async() => { XivCache.RebuildCache(); }); } })); }
//初期化 private LogLimit create(bool isDisplay) { var dat = new Dat(new[]{CtrlType.TextBox}); dat.Add(true, "AAA"); dat.Add(true, "表示"); dat.Add(true, "123"); dat.Add(true, "アイウ"); return new LogLimit(dat, isDisplay); }
//OneValの生成 //デフォルト値(nullを設定した場合、適切な値を自動でセットする) public static OneVal CreateOneVal(CtrlType ctrlType, Object val) { //Kernel kernel = new Kernel(); const string help = "help"; OneCtrl oneCtrl; switch (ctrlType) { case CtrlType.CheckBox: if (val == null) { val = true; } oneCtrl = new CtrlCheckBox(help); break; case CtrlType.Int: if (val == null) { val = 1; } oneCtrl = new CtrlInt(help, 3); // 3桁で決め打ち break; case CtrlType.File: if (val == null) { val = "1.txt"; } oneCtrl = new CtrlFile(help, 200, new Kernel()); break; case CtrlType.Folder: if (val == null) { val = "c:\temp"; } oneCtrl = new CtrlFolder(help, 200, new Kernel()); break; case CtrlType.TextBox: if (val == null) { val = "abc"; } oneCtrl = new CtrlTextBox(help, 20); break; case CtrlType.Radio: if (val == null) { val = 0; } oneCtrl = new CtrlRadio(help, new[] { "1", "2", "3" }, 30, 3); break; case CtrlType.Font: if (val == null) { val = new Font("MS ゴシック", 10f); } oneCtrl = new CtrlFont(help, LangKind.Jp); break; case CtrlType.Memo: if (val == null) { val = "1"; } oneCtrl = new CtrlMemo(help, 10, 10); break; case CtrlType.Hidden: if (val == null) { val = ""; } oneCtrl = new CtrlHidden(help, 30); break; case CtrlType.AddressV4: if (val == null) { val = ""; } oneCtrl = new CtrlAddress(help); break; case CtrlType.BindAddr: if (val == null) { val = "V4ONLY,INADDR_ANY,IN6ADDR_ANY_INIT"; } var list = new List <Ip>(); try { list.Add(new Ip(IpKind.InAddrAny)); list.Add(new Ip("192.168.0.1")); } catch (ValidObjException ex) { Assert.Fail(ex.Message); } oneCtrl = new CtrlBindAddr(help, list.ToArray(), list.ToArray()); break; case CtrlType.ComboBox: //listを{"1","2"}で決め打ち if (val == null) { val = 0; } oneCtrl = new CtrlComboBox(help, new[] { "1", "2" }, 10); break; case CtrlType.Dat: //カラムはTEXTBOX×2で決め打ち var listVal = new ListVal { new OneVal("name1", true, Crlf.Nextline, new CtrlCheckBox("help")), new OneVal("name2", true, Crlf.Nextline, new CtrlCheckBox("help")) }; if (val == null) { val = new Dat(new[] { CtrlType.CheckBox, CtrlType.CheckBox }); } oneCtrl = new CtrlDat(help, listVal, 300, LangKind.Jp); break; default: throw new Exception(ctrlType.ToString()); } return(new OneVal("name", val, Crlf.Nextline, oneCtrl)); }
public ChartFormatsSequence(IStreamReader reader) : base(reader) { // CHARTFOMATS = Chart Begin *2FONTLIST Scl PlotGrowth [FRAME] *SERIESFORMAT *SS ShtProps // *2DFTTEXT AxesUsed 1*2AXISPARENT [CrtLayout12A] [DAT] *ATTACHEDLABEL [CRTMLFRT] // *([DataLabExt StartObject] ATTACHEDLABEL [EndObject]) [TEXTPROPS] *2CRTMLFRT End // Chart this.Chart = (Chart)BiffRecord.ReadRecord(reader); // Begin this.Begin = (Begin)BiffRecord.ReadRecord(reader); // *2FONTLIST this.FontListSequences = new List <FontListSequence>(); while (BiffRecord.GetNextRecordType(reader) == RecordType.FrtFontList) { this.FontListSequences.Add(new FontListSequence(reader)); } // Scl this.Scl = (Scl)BiffRecord.ReadRecord(reader); // PlotGrowth this.PlotGrowth = (PlotGrowth)BiffRecord.ReadRecord(reader); // [FRAME] if (BiffRecord.GetNextRecordType(reader) == RecordType.Frame) { this.FrameSequence = new FrameSequence(reader); } // *SERIESFORMAT this.SeriesFormatSequences = new List <SeriesFormatSequence>(); while (BiffRecord.GetNextRecordType(reader) == RecordType.Series) { SeriesFormatSequence seriesFormatSequence = new SeriesFormatSequence(reader); // remember the index in the collection seriesFormatSequence.order = (UInt16)this.SeriesFormatSequences.Count; this.SeriesFormatSequences.Add(seriesFormatSequence); } // *SS this.SsSequences = new List <SsSequence>(); while (BiffRecord.GetNextRecordType(reader) == RecordType.DataFormat) { this.SsSequences.Add(new SsSequence(reader)); } // ShtProps this.ShtProps = (ShtProps)BiffRecord.ReadRecord(reader); // *2DFTTEXT this.DftTextSequences = new List <DftTextSequence>(); while (BiffRecord.GetNextRecordType(reader) == RecordType.DataLabExt || BiffRecord.GetNextRecordType(reader) == RecordType.DefaultText) { this.DftTextSequences.Add(new DftTextSequence(reader)); } // AxesUsed this.AxesUsed = (AxesUsed)BiffRecord.ReadRecord(reader); // 1*2AXISPARENT this.AxisParentSequences = new List <AxisParentSequence>(); while (BiffRecord.GetNextRecordType(reader) == RecordType.AxisParent) { this.AxisParentSequences.Add(new AxisParentSequence(reader)); } // [CrtLayout12A] if (BiffRecord.GetNextRecordType(reader) == RecordType.CrtLayout12A) { this.CrtLayout12A = (CrtLayout12)BiffRecord.ReadRecord(reader); } // [DAT] if (BiffRecord.GetNextRecordType(reader) == RecordType.Dat) { this.Dat = (Dat)BiffRecord.ReadRecord(reader); } // *ATTACHEDLABEL this.AttachedLabelSequences = new List <AttachedLabelSequence>(); while (BiffRecord.GetNextRecordType(reader) == RecordType.Text) { this.AttachedLabelSequences.Add(new AttachedLabelSequence(reader)); } // [CrtLayout12A] // NOTE: The occurence of a CrtLayout12A record at this position in the sequence // is a deviation from the spec. However it has been encountered in certain // test documents (even if these documents were re-saved using Excel 2003) // if (BiffRecord.GetNextRecordType(reader) == RecordType.CrtLayout12A) { this.CrtLayout12A = (CrtLayout12)BiffRecord.ReadRecord(reader); } // [CRTMLFRT] if (BiffRecord.GetNextRecordType(reader) == RecordType.CrtMlFrt) { this.CrtMlfrtSequence = new CrtMlfrtSequence(reader); } // [CrtLayout12A] // NOTE: The occurence of a CrtLayout12A record at this position in the sequence // is a deviation from the spec. However it has been encountered in certain // test documents (even if these documents were re-saved using Excel 2003) // if (BiffRecord.GetNextRecordType(reader) == RecordType.CrtLayout12A) { this.CrtLayout12A = (CrtLayout12)BiffRecord.ReadRecord(reader); } // *([DataLabExt StartObject] ATTACHEDLABEL [EndObject]) this.DataLabelGroups = new List <DataLabelGroup>(); while (BiffRecord.GetNextRecordType(reader) == RecordType.DataLabExt || BiffRecord.GetNextRecordType(reader) == RecordType.Text) { this.DataLabelGroups.Add(new DataLabelGroup(reader)); } // [CrtLayout12A] // NOTE: The occurence of a CrtLayout12A record at this position in the sequence // is a deviation from the spec. However it has been encountered in certain // test documents (even if these documents were re-saved using Excel 2003) // if (BiffRecord.GetNextRecordType(reader) == RecordType.CrtLayout12A) { this.CrtLayout12A = (CrtLayout12)BiffRecord.ReadRecord(reader); } // [TEXTPROPS] if (BiffRecord.GetNextRecordType(reader) == RecordType.RichTextStream || BiffRecord.GetNextRecordType(reader) == RecordType.TextPropsStream) { this.TextPropsSequence = new TextPropsSequence(reader); } // [CrtLayout12A] // NOTE: The occurence of a CrtLayout12A record at this position in the sequence // is a deviation from the spec. However it has been encountered in certain // test documents (even if these documents were re-saved using Excel 2003) // if (BiffRecord.GetNextRecordType(reader) == RecordType.CrtLayout12A) { this.CrtLayout12A = (CrtLayout12)BiffRecord.ReadRecord(reader); } // *2CRTMLFRT this.CrtMlfrtSequences = new List <CrtMlfrtSequence>(); while (BiffRecord.GetNextRecordType(reader) == RecordType.CrtMlFrt) { this.CrtMlfrtSequences.Add(new CrtMlfrtSequence(reader)); } // End this.End = (End)BiffRecord.ReadRecord(reader); }
public Tex(DirectoryInfo gameDirectory) { _gameDirectory = gameDirectory; _index = new Index(_gameDirectory); _dat = new Dat(_gameDirectory); }
/// <summary> /// Gets the skeleton sklb file /// </summary> /// <param name="modelName">The name of the model</param> /// <param name="category">The items category</param> private async Task GetSkeleton(string modelName, string category) { var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var skelFolder = ""; var skelFile = ""; var slotAbr = ""; if (modelName[0].Equals('w')) { skelFolder = string.Format(XivStrings.WeapSkelFolder, modelName.Substring(1, 4), "0001"); skelFile = string.Format(XivStrings.WeapSkelFile, modelName.Substring(1, 4), "0001"); } else if (modelName[0].Equals('m')) { skelFolder = string.Format(XivStrings.MonsterSkelFolder, modelName.Substring(1, 4), "0001"); skelFile = string.Format(XivStrings.MonsterSkelFile, modelName.Substring(1, 4), "0001"); } else if (modelName[0].Equals('d')) { skelFolder = string.Format(XivStrings.DemiSkelFolder, modelName.Substring(1, 4), "0001"); skelFile = string.Format(XivStrings.DemiSkelFile, modelName.Substring(1, 4), "0001"); } else { slotAbr = SlotAbbreviationDictionary[category]; var id = modelName.Substring(6, 4); if (_item.SecondaryCategory.Equals(XivStrings.Hair)) { id = _hairSklbName.Substring(1); } if (slotAbr.Equals("base")) { id = "0001"; } skelFolder = string.Format(XivStrings.EquipSkelFolder, modelName.Substring(1, 4), slotAbr, slotAbr[0], id); skelFile = string.Format(XivStrings.EquipSkelFile, modelName.Substring(1, 4), slotAbr[0], id); } // Continue only if the skeleton file exists if (!await index.FileExists(HashGenerator.GetHash(skelFile), HashGenerator.GetHash(skelFolder), _dataFile)) { // Sometimes for face skeletons id 0001 does not exist but 0002 does if (_item.SecondaryCategory.Equals(XivStrings.Face)) { skelFolder = string.Format(XivStrings.EquipSkelFolder, modelName.Substring(1, 4), slotAbr, slotAbr[0], "0002"); skelFile = string.Format(XivStrings.EquipSkelFile, modelName.Substring(1, 4), slotAbr[0], "0002"); if (!await index.FileExists(HashGenerator.GetHash(skelFile), HashGenerator.GetHash(skelFolder), _dataFile)) { return; } } else { return; } } var offset = await index.GetDataOffset(HashGenerator.GetHash(skelFolder), HashGenerator.GetHash(skelFile), _dataFile); if (offset == 0) { throw new Exception($"Could not find offset for {skelFolder}/{skelFile}"); } var sklbData = await dat.GetType2Data(offset, _dataFile); using (var br = new BinaryReader(new MemoryStream(sklbData))) { br.BaseStream.Seek(0, SeekOrigin.Begin); var magic = br.ReadInt32(); var format = br.ReadInt32(); br.ReadBytes(2); if (magic != 0x736B6C62) { throw new FormatException(); } var dataOffset = 0; switch (format) { case 0x31323030: dataOffset = br.ReadInt16(); break; case 0x31333030: case 0x31333031: br.ReadBytes(2); dataOffset = br.ReadInt16(); break; default: throw new Exception($"Unkown Data Format ({format})"); } br.BaseStream.Seek(dataOffset, SeekOrigin.Begin); var havokData = br.ReadBytes(sklbData.Length - dataOffset); var mName = modelName.Substring(0, 5); if (category.Equals(XivStrings.Head)) { mName = modelName.Substring(5, 5); } else if (category.Equals(XivStrings.Hair)) { mName = _hairSklbName; } File.WriteAllBytes(Directory.GetCurrentDirectory() + "/Skeletons/" + mName + ".sklb", havokData); } }
private async Task CreateBasic() { string modPackPath = Path.Combine(Properties.Settings.Default.ModPack_Directory, $"{ViewModel.Name}.ttmp2"); if (File.Exists(modPackPath)) { DialogResult overwriteDialogResult = FlexibleMessageBox.Show(new Wpf32Window(this), UIMessages.ModPackOverwriteMessage, UIMessages.OverwriteTitle, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning); if (overwriteDialogResult != System.Windows.Forms.DialogResult.Yes) { return; } } TTMP texToolsModPack = new TTMP(new DirectoryInfo(Settings.Default.ModPack_Directory), XivStrings.TexTools); var index = new Index(XivCache.GameInfo.GameDirectory); var dat = new Dat(XivCache.GameInfo.GameDirectory); var modding = new Modding(XivCache.GameInfo.GameDirectory); var ModList = modding.GetModList(); SimpleModPackData simpleModPackData = new SimpleModPackData { Name = ViewModel.Name, Author = ViewModel.Author, Version = ViewModel.Version, Description = ViewModel.Description, Url = ViewModel.Url, SimpleModDataList = new List <SimpleModData>() }; foreach (var entry in ViewModel.Entries) { foreach (var file in entry.AllFiles) { var exists = await index.FileExists(file); // This is a funny case where in order to create the modpack we actually have to write a default meta entry to the dats first. // If we had the right functions we could just load and serialize the data, but we don't atm. if (!exists && Path.GetExtension(file) == ".meta") { var meta = await ItemMetadata.GetMetadata(file); await ItemMetadata.SaveMetadata(meta, XivStrings.TexTools); } var offset = await index.GetDataOffset(file); var dataFile = IOUtil.GetDataFileFromPath(file); var compressedSize = await dat.GetCompressedFileSize(offset, dataFile); var modEntry = ModList.Mods.FirstOrDefault(x => x.fullPath == file); var modded = modEntry != null && modEntry.enabled == true; SimpleModData simpleData = new SimpleModData { Name = entry.Item.Name, Category = entry.Item.SecondaryCategory, FullPath = file, ModOffset = offset, ModSize = compressedSize, IsDefault = !modded, DatFile = dataFile.GetDataFileName() }; simpleModPackData.SimpleModDataList.Add(simpleData); } } try { await LockUi(UIStrings.Creating_Modpack, null, null); Progress <(int current, int total, string message)> progressIndicator = new Progress <(int current, int total, string message)>(ReportProgress); await texToolsModPack.CreateSimpleModPack(simpleModPackData, XivCache.GameInfo.GameDirectory, progressIndicator, true); FlexibleMessageBox.Show(new Wpf32Window(this), "Modpack Created Successfully.", "Modpack Created", MessageBoxButtons.OK, MessageBoxIcon.Information); await UnlockUi(this); DialogResult = true; } catch (Exception ex) { FlexibleMessageBox.Show(new Wpf32Window(this), "An Error occured while creating the modpack.\n\n" + ex.Message, "Modpack Creation Error", MessageBoxButtons.OK, MessageBoxIcon.Error); await UnlockUi(this); } }
public void Given_a_valid_dat_file_When_a_DAT_object_is_created_Then_the_count_property_returns_a_count_of_content_files() { Dat df = new Dat(Utils.ReadFile("basic.dat")); Assert.AreEqual(2, df.Count); }
public void SetUp() { var datUser = new Dat(new CtrlType[]{CtrlType.TextBox, CtrlType.TextBox}); datUser.Add(true, "user1\t3OuFXZzV8+iY6TC747UpCA=="); _mailBox = new MailBox(new Logger(), datUser, "c:\\tmp2\\bjd5\\SmtpServerTest\\mailbox"); }
/// <summary> /// Gets the full IMC information for a given item /// </summary> /// <param name="item"></param> /// <param name="useSecondary">Determines if the SecondaryModelInfo should be used instead.(XivGear only)</param> /// <returns>The ImcData data</returns> public async Task <FullImcInfo> GetFullImcInfo(string path) { var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var imcOffset = await index.GetDataOffset(path); if (imcOffset == 0) { throw new InvalidDataException($"Could not find offset for {path}"); } var imcByteData = await dat.GetType2Data(imcOffset, _dataFile); return(await Task.Run(() => { using (var br = new BinaryReader(new MemoryStream(imcByteData))) { var subsetCount = br.ReadInt16(); var identifier = br.ReadInt16(); var imcData = new FullImcInfo() { TypeIdentifier = (ImcType)identifier, DefaultSubset = new List <XivImc>(), SubsetList = new List <List <XivImc> >(subsetCount) }; //weapons and monsters do not have variant sets if (imcData.TypeIdentifier == ImcType.NonSet) { // Identifier used by weapons and monsters. imcData.DefaultSubset.Add(new XivImc { Variant = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }); for (var i = 0; i < subsetCount; i++) { var subset = new List <XivImc>() { new XivImc { Variant = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() } }; } } else if (imcData.TypeIdentifier == ImcType.Set) { // Identifier used by Equipment. imcData.DefaultSubset = new List <XivImc>() { new XivImc { Variant = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, new XivImc { Variant = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, new XivImc { Variant = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, new XivImc { Variant = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, new XivImc { Variant = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, }; for (var i = 0; i < subsetCount; i++) { // gets the data for each slot in the current variant set var imcGear = new List <XivImc>() { new XivImc { Variant = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, new XivImc { Variant = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, new XivImc { Variant = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, new XivImc { Variant = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, new XivImc { Variant = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, }; imcData.SubsetList.Add(imcGear); } } else { throw new NotSupportedException("Unknown IMC Type Identifier. (Please report this item in the TexTools Discord #bug_reports channel.)"); } return imcData; } })); }
public void 一部が重複する2つのリソースの追加() { //setUp var dat = new Dat(new CtrlType[5]); dat.Add(true, "0\tns\talias\t192.168.0.1\t10"); dat.Add(true, "1\tns\talias\t192.168.0.1\t10"); var sut = new RrDb(null, null, dat, "example.com", true); //(1)a ns.example.com. 192.168.0.1 //(2)ptr 1.0.168.192.in.addr.ptr ns.example.com. //(3)ns example.com. ns.example.com. var expected = 3; //exercise int actual = Size(sut); //verify Assert.That(actual, Is.EqualTo(expected)); }
/// <summary> /// Creates a mod pack that uses simple installation /// </summary> /// <param name="modPackData">The data that will go into the mod pack</param> /// <param name="gameDirectory">The game directory</param> /// <param name="progress">The progress of the mod pack creation</param> /// <returns>The number of mods processed for the mod pack</returns> public async Task <int> CreateSimpleModPack(SimpleModPackData modPackData, DirectoryInfo gameDirectory, IProgress <double> progress) { var processCount = await Task.Run <int>(() => { var dat = new Dat(gameDirectory); _tempMPD = Path.GetTempFileName(); _tempMPL = Path.GetTempFileName(); var modCount = 1; var modPackJson = new ModPackJson { TTMPVersion = _currentSimpleTTMPVersion, Name = modPackData.Name, Author = modPackData.Author, Version = modPackData.Version.ToString(), Description = modPackData.Description, SimpleModsList = new List <ModsJson>() }; using (var binaryWriter = new BinaryWriter(File.Open(_tempMPD, FileMode.Open))) { foreach (var simpleModData in modPackData.SimpleModDataList) { var modsJson = new ModsJson { Name = simpleModData.Name, Category = simpleModData.Category, FullPath = simpleModData.FullPath, ModSize = simpleModData.ModSize, DatFile = simpleModData.DatFile, ModOffset = binaryWriter.BaseStream.Position }; var rawData = dat.GetRawData((int)simpleModData.ModOffset, XivDataFiles.GetXivDataFile(simpleModData.DatFile), simpleModData.ModSize); binaryWriter.Write(rawData); modPackJson.SimpleModsList.Add(modsJson); progress?.Report((double)modCount / modPackData.SimpleModDataList.Count); modCount++; } } File.WriteAllText(_tempMPL, JsonConvert.SerializeObject(modPackJson)); var modPackPath = $"{_modPackDirectory}\\{modPackData.Name}.ttmp"; if (File.Exists(modPackPath)) { var fileNum = 1; modPackPath = $"{_modPackDirectory}\\{modPackData.Name}({fileNum}).ttmp"; while (File.Exists(modPackPath)) { fileNum++; modPackPath = $"{_modPackDirectory}\\{modPackData.Name}({fileNum}).ttmp"; } } using (var zip = ZipFile.Open(modPackPath, ZipArchiveMode.Create)) { zip.CreateEntryFromFile(_tempMPL, "TTMPL.mpl"); zip.CreateEntryFromFile(_tempMPD, "TTMPD.mpd"); } File.Delete(_tempMPD); File.Delete(_tempMPL); return(modCount); }); return(processCount); }
/// <summary> /// Imports a mod pack asynchronously /// </summary> /// <param name="modPackDirectory">The directory of the mod pack</param> /// <param name="modsJson">The list of mods to be imported</param> /// <param name="gameDirectory">The game directory</param> /// <param name="modListDirectory">The mod list directory</param> /// <param name="progress">The progress of the import</param> /// <returns>The number of total mods imported</returns> public async Task <int> ImportModPackAsync(DirectoryInfo modPackDirectory, List <ModsJson> modsJson, DirectoryInfo gameDirectory, DirectoryInfo modListDirectory, IProgress <double> progress) { var processCount = await Task.Run <int>(() => { var dat = new Dat(gameDirectory); var modListFullPaths = new List <string>(); var modList = JsonConvert.DeserializeObject <ModList>(File.ReadAllText(modListDirectory.FullName)); var modCount = 1; foreach (var modListMod in modList.Mods) { modListFullPaths.Add(modListMod.fullPath); } using (var archive = ZipFile.OpenRead(modPackDirectory.FullName)) { foreach (var zipEntry in archive.Entries) { if (zipEntry.FullName.EndsWith(".mpd")) { _tempMPD = Path.GetTempFileName(); zipEntry.ExtractToFile(_tempMPD, true); using (var binaryReader = new BinaryReader(File.OpenRead(_tempMPD))) { foreach (var modJson in modsJson) { if (modListFullPaths.Contains(modJson.FullPath)) { var existingEntry = (from entry in modList.Mods where entry.fullPath.Equals(modJson.FullPath) select entry).FirstOrDefault(); binaryReader.BaseStream.Seek(modJson.ModOffset, SeekOrigin.Begin); var data = binaryReader.ReadBytes(modJson.ModSize); dat.WriteToDat(new List <byte>(data), existingEntry, modJson.FullPath, modJson.Category, modJson.Name, XivDataFiles.GetXivDataFile(modJson.DatFile), _source, GetDataType(modJson.FullPath)); } else { binaryReader.BaseStream.Seek(modJson.ModOffset, SeekOrigin.Begin); var data = binaryReader.ReadBytes(modJson.ModSize); dat.WriteToDat(new List <byte>(data), null, modJson.FullPath, modJson.Category, modJson.Name, XivDataFiles.GetXivDataFile(modJson.DatFile), _source, GetDataType(modJson.FullPath)); } progress?.Report((double)modCount / modsJson.Count); modCount++; } } File.Delete(_tempMPD); break; } } } return(modCount - 1); }); return(processCount); }
private async Task AddFile(FileEntry file, IItem item, byte[] rawData = null) { var dat = new Dat(_gameDirectory); var index = new Index(_gameDirectory); if (file == null || file.Path == null || _selectedModOption == null) { return; } var includedModsList = IncludedModsList.Items.Cast <FileEntry>().ToList(); if (includedModsList.Any(f => f.Path.Equals(file.Path))) { if (FlexibleMessageBox.Show( string.Format(UIMessages.ExistingOption, file.Name), UIMessages.OverwriteTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question) != System.Windows.Forms.DialogResult.Yes) { return; } } if (rawData == null) { var df = IOUtil.GetDataFileFromPath(file.Path); var offset = await index.GetDataOffset(file.Path); if (offset <= 0) { FlexibleMessageBox.Show("Cannot include file, file offset invalid.", UIMessages.ModDataReadErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } var size = await dat.GetCompressedFileSize(offset, df); rawData = dat.GetRawData(offset, df, size); if (rawData == null) { FlexibleMessageBox.Show("Cannot include file, file offset invalid.", UIMessages.ModDataReadErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } if (_selectedModOption.Mods.ContainsKey(file.Path)) { _selectedModOption.Mods[file.Path].ModDataBytes = rawData; } else { IncludedModsList.Items.Add(file); var modData = new ModData { Name = item.Name, Category = item.SecondaryCategory, FullPath = file.Path, ModDataBytes = rawData, }; _selectedModOption.Mods.Add(file.Path, modData); } }
/// <summary> /// Copies the entirety of a given root to a new root. /// </summary> /// <param name="Source">Original Root to copy from.</param> /// <param name="Destination">Destination root to copy to.</param> /// <param name="ApplicationSource">Application to list as the source for the resulting mod entries.</param> /// <returns>Returns a Dictionary of all the file conversion</returns> public static async Task <Dictionary <string, string> > CloneRoot(XivDependencyRoot Source, XivDependencyRoot Destination, string ApplicationSource, int singleVariant = -1, string saveDirectory = null, IProgress <string> ProgressReporter = null, IndexFile index = null, ModList modlist = null, ModPack modPack = null) { if (!IsSupported(Source) || !IsSupported(Destination)) { throw new InvalidDataException("Cannot clone unsupported root."); } if (ProgressReporter != null) { ProgressReporter.Report("Stopping Cache Worker..."); } var workerStatus = XivCache.CacheWorkerEnabled; XivCache.CacheWorkerEnabled = false; try { var df = IOUtil.GetDataFileFromPath(Source.ToString()); var _imc = new Imc(XivCache.GameInfo.GameDirectory); var _mdl = new Mdl(XivCache.GameInfo.GameDirectory, df); var _dat = new Dat(XivCache.GameInfo.GameDirectory); var _index = new Index(XivCache.GameInfo.GameDirectory); var _mtrl = new Mtrl(XivCache.GameInfo.GameDirectory); var _modding = new Modding(XivCache.GameInfo.GameDirectory); var doSave = false; if (index == null) { doSave = true; index = await _index.GetIndexFile(df); modlist = await _modding.GetModListAsync(); } bool locked = _index.IsIndexLocked(df); if (locked) { throw new Exception("Game files currently in use."); } if (ProgressReporter != null) { ProgressReporter.Report("Analyzing items and variants..."); } // First, try to get everything, to ensure it's all valid. ItemMetadata originalMetadata = await GetCachedMetadata(index, modlist, Source, df, _dat); var originalModelPaths = await Source.GetModelFiles(index, modlist); var originalMaterialPaths = await Source.GetMaterialFiles(-1, index, modlist); var originalTexturePaths = await Source.GetTextureFiles(-1, index, modlist); var originalVfxPaths = new HashSet <string>(); if (Imc.UsesImc(Source)) { var avfxSets = originalMetadata.ImcEntries.Select(x => x.Vfx).Distinct(); foreach (var avfx in avfxSets) { var avfxStuff = await ATex.GetVfxPath(Source.Info, avfx); if (String.IsNullOrEmpty(avfxStuff.Folder) || String.IsNullOrEmpty(avfxStuff.File)) { continue; } var path = avfxStuff.Folder + "/" + avfxStuff.File; if (index.FileExists(path)) { originalVfxPaths.Add(path); } } } // Time to start editing things. // First, get a new, clean copy of the metadata, pointed at the new root. var newMetadata = await GetCachedMetadata(index, modlist, Source, df, _dat); newMetadata.Root = Destination.Info.ToFullRoot(); ItemMetadata originalDestinationMetadata = null; try { originalDestinationMetadata = await GetCachedMetadata(index, modlist, Destination, df, _dat); } catch { originalDestinationMetadata = new ItemMetadata(Destination); } // Set 0 needs special handling. if (Source.Info.PrimaryType == XivItemType.equipment && Source.Info.PrimaryId == 0) { var set1Root = new XivDependencyRoot(Source.Info.PrimaryType, 1, null, null, Source.Info.Slot); var set1Metadata = await GetCachedMetadata(index, modlist, set1Root, df, _dat); newMetadata.EqpEntry = set1Metadata.EqpEntry; if (Source.Info.Slot == "met") { newMetadata.GmpEntry = set1Metadata.GmpEntry; } } else if (Destination.Info.PrimaryType == XivItemType.equipment && Destination.Info.PrimaryId == 0) { newMetadata.EqpEntry = null; newMetadata.GmpEntry = null; } // Now figure out the path names for all of our new paths. // These dictionarys map Old Path => New Path Dictionary <string, string> newModelPaths = new Dictionary <string, string>(); Dictionary <string, string> newMaterialPaths = new Dictionary <string, string>(); Dictionary <string, string> newMaterialFileNames = new Dictionary <string, string>(); Dictionary <string, string> newTexturePaths = new Dictionary <string, string>(); Dictionary <string, string> newAvfxPaths = new Dictionary <string, string>(); if (ProgressReporter != null) { ProgressReporter.Report("Calculating files to copy..."); } // For each path, replace any instances of our primary and secondary types. foreach (var path in originalModelPaths) { newModelPaths.Add(path, UpdatePath(Source, Destination, path)); } foreach (var path in originalMaterialPaths) { var nPath = UpdatePath(Source, Destination, path); newMaterialPaths.Add(path, nPath); var fName = Path.GetFileName(path); if (!newMaterialFileNames.ContainsKey(fName)) { newMaterialFileNames.Add(fName, Path.GetFileName(nPath)); } } foreach (var path in originalTexturePaths) { newTexturePaths.Add(path, UpdatePath(Source, Destination, path)); } foreach (var path in originalVfxPaths) { newAvfxPaths.Add(path, UpdatePath(Source, Destination, path)); } var destItem = Destination.GetFirstItem(); var srcItem = (await Source.GetAllItems(singleVariant))[0]; var iCat = destItem.SecondaryCategory; var iName = destItem.Name; var files = newModelPaths.Select(x => x.Value).Union( newMaterialPaths.Select(x => x.Value)).Union( newAvfxPaths.Select(x => x.Value)).Union( newTexturePaths.Select(x => x.Value)); var allFiles = new HashSet <string>(); foreach (var f in files) { allFiles.Add(f); } allFiles.Add(Destination.Info.GetRootFile()); if (ProgressReporter != null) { ProgressReporter.Report("Getting modlist..."); } if (ProgressReporter != null) { ProgressReporter.Report("Removing existing modifications to destination root..."); } if (Destination != Source) { var dPath = Destination.Info.GetRootFolder(); var allMods = modlist.Mods.ToList(); foreach (var mod in allMods) { if (mod.fullPath.StartsWith(dPath) && !mod.IsInternal()) { if (Destination.Info.SecondaryType != null || Destination.Info.Slot == null) { // If this is a slotless root, purge everything. await _modding.DeleteMod(mod.fullPath, false, index, modlist); } else if (allFiles.Contains(mod.fullPath) || mod.fullPath.Contains(Destination.Info.GetBaseFileName(true))) { // Otherwise, only purge the files we're replacing, and anything else that // contains our slot name. await _modding.DeleteMod(mod.fullPath, false, index, modlist); } } } } if (ProgressReporter != null) { ProgressReporter.Report("Copying models..."); } // Load, Edit, and resave the model files. foreach (var kv in newModelPaths) { var src = kv.Key; var dst = kv.Value; var offset = index.Get8xDataOffset(src); var xmdl = await _mdl.GetRawMdlData(src, false, offset); var tmdl = TTModel.FromRaw(xmdl); if (xmdl == null || tmdl == null) { continue; } tmdl.Source = dst; xmdl.MdlPath = dst; // Replace any material references as needed. foreach (var m in tmdl.MeshGroups) { foreach (var matKv in newMaterialFileNames) { m.Material = m.Material.Replace(matKv.Key, matKv.Value); } } // Save new Model. var bytes = await _mdl.MakeNewMdlFile(tmdl, xmdl, null); await _dat.WriteModFile(bytes, dst, ApplicationSource, destItem, index, modlist); } if (ProgressReporter != null) { ProgressReporter.Report("Copying textures..."); } // Raw Copy all Texture files to the new destinations to avoid having the MTRL save functions auto-generate blank textures. foreach (var kv in newTexturePaths) { var src = kv.Key; var dst = kv.Value; await _dat.CopyFile(src, dst, ApplicationSource, true, destItem, index, modlist); } if (ProgressReporter != null) { ProgressReporter.Report("Copying materials..."); } HashSet <string> CopiedMaterials = new HashSet <string>(); // Load every Material file and edit the texture references to the new texture paths. foreach (var kv in newMaterialPaths) { var src = kv.Key; var dst = kv.Value; try { var offset = index.Get8xDataOffset(src); if (offset == 0) { continue; } var xivMtrl = await _mtrl.GetMtrlData(offset, src, 11); xivMtrl.MTRLPath = dst; for (int i = 0; i < xivMtrl.TexturePathList.Count; i++) { foreach (var tkv in newTexturePaths) { xivMtrl.TexturePathList[i] = xivMtrl.TexturePathList[i].Replace(tkv.Key, tkv.Value); } } await _mtrl.ImportMtrl(xivMtrl, destItem, ApplicationSource, index, modlist); CopiedMaterials.Add(dst); } catch (Exception ex) { // Let functions later handle this mtrl then. } } if (ProgressReporter != null) { ProgressReporter.Report("Copying VFX..."); } // Copy VFX files. foreach (var kv in newAvfxPaths) { var src = kv.Key; var dst = kv.Value; await _dat.CopyFile(src, dst, ApplicationSource, true, destItem, index, modlist); } if (ProgressReporter != null) { ProgressReporter.Report("Creating missing variants..."); } // Check to see if we need to add any variants var cloneNum = newMetadata.ImcEntries.Count >= 2 ? 1 : 0; while (originalDestinationMetadata.ImcEntries.Count > newMetadata.ImcEntries.Count) { // Clone Variant 1 into the variants we are missing. newMetadata.ImcEntries.Add((XivImc)newMetadata.ImcEntries[cloneNum].Clone()); } if (singleVariant >= 0) { if (ProgressReporter != null) { ProgressReporter.Report("Setting single-variant data..."); } if (singleVariant < newMetadata.ImcEntries.Count) { var v = newMetadata.ImcEntries[singleVariant]; for (int i = 0; i < newMetadata.ImcEntries.Count; i++) { newMetadata.ImcEntries[i] = (XivImc)v.Clone(); } } } // Update Skeleton references to be for the correct set Id. var setId = Destination.Info.SecondaryId == null ? (ushort)Destination.Info.PrimaryId : (ushort)Destination.Info.SecondaryId; foreach (var entry in newMetadata.EstEntries) { entry.Value.SetId = setId; } if (ProgressReporter != null) { ProgressReporter.Report("Copying metdata..."); } // Poke through the variants and adjust any that point to null Material Sets to instead use a valid one. if (newMetadata.ImcEntries.Count > 0 && originalMetadata.ImcEntries.Count > 0) { var valid = newMetadata.ImcEntries.FirstOrDefault(x => x.MaterialSet != 0).MaterialSet; if (valid <= 0) { valid = originalMetadata.ImcEntries.FirstOrDefault(x => x.MaterialSet != 0).MaterialSet; } for (int i = 0; i < newMetadata.ImcEntries.Count; i++) { var entry = newMetadata.ImcEntries[i]; if (entry.MaterialSet == 0) { entry.MaterialSet = valid; } } } await ItemMetadata.SaveMetadata(newMetadata, ApplicationSource, index, modlist); // Save the new Metadata file via the batch function so that it's only written to the memory cache for now. await ItemMetadata.ApplyMetadataBatched(new List <ItemMetadata>() { newMetadata }, index, modlist, false); if (ProgressReporter != null) { ProgressReporter.Report("Filling in missing material sets..."); } // Validate all variants/material sets for valid materials, and copy materials as needed to fix. if (Imc.UsesImc(Destination)) { var mSets = newMetadata.ImcEntries.Select(x => x.MaterialSet).Distinct(); foreach (var mSetId in mSets) { var path = Destination.Info.GetRootFolder() + "material/v" + mSetId.ToString().PadLeft(4, '0') + "/"; foreach (var mkv in newMaterialFileNames) { // See if the material was copied over. var destPath = path + mkv.Value; if (CopiedMaterials.Contains(destPath)) { continue; } string existentCopy = null; // If not, find a material where one *was* copied over. foreach (var mSetId2 in mSets) { var p2 = Destination.Info.GetRootFolder() + "material/v" + mSetId2.ToString().PadLeft(4, '0') + "/"; foreach (var cmat2 in CopiedMaterials) { if (cmat2 == p2 + mkv.Value) { existentCopy = cmat2; break; } } } // Shouldn't ever actually hit this, but if we do, nothing to be done about it. if (existentCopy == null) { continue; } // Copy the material over. await _dat.CopyFile(existentCopy, destPath, ApplicationSource, true, destItem, index, modlist); } } } if (ProgressReporter != null) { ProgressReporter.Report("Updating modlist..."); } if (modPack == null) { modPack = new ModPack() { author = "System", name = "Item Copy - " + srcItem.Name + " to " + iName, url = "", version = "1.0" }; } List <Mod> mods = new List <Mod>(); foreach (var mod in modlist.Mods) { if (allFiles.Contains(mod.fullPath)) { // Ensure all of our modified files are attributed correctly. mod.name = iName; mod.category = iCat; mod.source = ApplicationSource; mod.modPack = modPack; mods.Add(mod); } } if (!modlist.ModPacks.Any(x => x.name == modPack.name)) { modlist.ModPacks.Add(modPack); } if (doSave) { // Save everything. await _index.SaveIndexFile(index); await _modding.SaveModListAsync(modlist); } XivCache.QueueDependencyUpdate(allFiles.ToList()); if (saveDirectory != null) { ProgressReporter.Report("Creating TTMP File..."); var desc = "Item Converter Modpack - " + srcItem.Name + " -> " + iName + "\nCreated at: " + DateTime.Now.ToString(); // Time to save the modlist to file. var dir = new DirectoryInfo(saveDirectory); var _ttmp = new TTMP(dir, ApplicationSource); var smpd = new SimpleModPackData() { Author = modPack.author, Description = desc, Url = modPack.url, Version = new Version(1, 0, 0), Name = modPack.name, SimpleModDataList = new List <SimpleModData>() }; foreach (var mod in mods) { var size = await _dat.GetCompressedFileSize(mod.data.modOffset, df); var smd = new SimpleModData() { Name = iName, FullPath = mod.fullPath, DatFile = df.GetDataFileName(), Category = iCat, IsDefault = false, ModSize = size, ModOffset = mod.data.modOffset }; smpd.SimpleModDataList.Add(smd); } await _ttmp.CreateSimpleModPack(smpd, XivCache.GameInfo.GameDirectory, null, true); } if (ProgressReporter != null) { ProgressReporter.Report("Root copy complete."); } // Return the final file conversion listing. var ret = newModelPaths.Union(newMaterialPaths).Union(newAvfxPaths).Union(newTexturePaths); var dict = ret.ToDictionary(x => x.Key, x => x.Value); dict.Add(Source.Info.GetRootFile(), Destination.Info.GetRootFile()); return(dict); } finally { XivCache.CacheWorkerEnabled = workerStatus; } }
/// <summary> /// Performs the most low-level mod enable/disable functions, without saving the modlist, /// ergo this should only be called by functions which will handle saving the modlist after /// they're done performing all modlist operations. /// /// If the Index and modlist are provided, the actions are only applied to those cached entries, rather /// than to the live files. /// </summary> /// <param name="enable"></param> /// <param name="mod"></param> /// <returns></returns> public async Task <bool> ToggleModUnsafe(bool enable, Mod mod, bool includeInternal, bool updateCache, IndexFile cachedIndex = null, ModList cachedModlist = null) { if (mod == null) { return(false); } if (string.IsNullOrEmpty(mod.name)) { return(false); } if (string.IsNullOrEmpty(mod.fullPath)) { return(false); } if (mod.data.originalOffset <= 0 && !enable) { throw new Exception("Cannot disable mod with invalid original offset."); } if (enable && mod.data.modOffset <= 0) { throw new Exception("Cannot enable mod with invalid mod offset."); } if (mod.IsInternal() && !includeInternal) { // Don't allow toggling internal mods unless we were specifically told to. return(false); } var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); // Added file. if (enable) { if (cachedIndex != null) { cachedIndex.SetDataOffset(mod.fullPath, mod.data.modOffset); } else { await index.UpdateDataOffset(mod.data.modOffset, mod.fullPath, false); } mod.enabled = true; if (cachedIndex == null) { // Check if we're re-enabling a metadata mod. var ext = Path.GetExtension(mod.fullPath); if (ext == ".meta") { var df = IOUtil.GetDataFileFromPath(mod.fullPath); // Retreive the uncompressed meta entry we just enabled. var data = await dat.GetType2Data(mod.data.modOffset, df); var meta = await ItemMetadata.Deserialize(data); meta.Validate(mod.fullPath); // And write that metadata to the actual constituent files. await ItemMetadata.ApplyMetadata(meta, cachedIndex, cachedModlist); } else if (ext == ".rgsp") { await CMP.ApplyRgspFile(mod.fullPath, cachedIndex, cachedModlist); } } } else if (!enable) { if (mod.IsCustomFile()) { // Delete file descriptor handles removing metadata as needed on its own. if (cachedIndex != null) { cachedIndex.SetDataOffset(mod.fullPath, 0); } else { await index.DeleteFileDescriptor(mod.fullPath, IOUtil.GetDataFileFromPath(mod.fullPath), false); } } else { if (cachedIndex != null) { cachedIndex.SetDataOffset(mod.fullPath, mod.data.originalOffset); } else { await index.UpdateDataOffset(mod.data.originalOffset, mod.fullPath, false); } } mod.enabled = false; } if (updateCache) { XivCache.QueueDependencyUpdate(mod.fullPath); } return(true); }
MlUserList CreateMlUsers2() { var kernel = new Kernel(null, null, null, null); var logger = new Logger(kernel, "", false, null); //参加者 MemberList = new Dat(); bool manager = false; MemberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER1", "*****@*****.**", manager, true, true, "")); //読者・投稿 MemberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER2", "*****@*****.**", manager, true, false, ""));//読者 × MemberList.Add(false, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER6", "*****@*****.**", manager, false, true, ""));//× 投稿 (Disable) MemberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "USER3", "*****@*****.**", manager, false, true, ""));//× 投稿 manager = true;//管理者 MemberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "ADMIN", "*****@*****.**", manager, false, true, "123"));//× 投稿 MemberList.Add(true, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "ADMIN2", "*****@*****.**", manager, true, true, "456"));//読者 投稿 MemberList.Add(false, string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", "ADMIN3", "*****@*****.**", manager, true, true, "789"));//読者 投稿 (Disable) var mlUserList = new MlUserList(MemberList); return mlUserList; }
private static async Task <ItemMetadata> GetCachedMetadata(IndexFile index, ModList modlist, XivDependencyRoot root, XivDataFile df, Dat _dat) { var originalMetadataOffset = index.Get8xDataOffset(root.Info.GetRootFile()); ItemMetadata originalMetadata = null; if (originalMetadataOffset == 0) { originalMetadata = await ItemMetadata.GetMetadata(root); } else { var data = await _dat.GetType2Data(originalMetadataOffset, df); originalMetadata = await ItemMetadata.Deserialize(data); } return(originalMetadata); }