├── Cafe.Matcha ├── Constant │ ├── .gitignore │ ├── Region.cs │ ├── FishEventBiteType.cs │ ├── FishEventType.cs │ ├── RequestType.cs │ ├── TreasureShiftingWheelResultType.cs │ ├── Secret.cs │ ├── ActorControlType.cs │ ├── LogType.cs │ ├── EventType.cs │ └── MatchaOpcode.cs ├── GitHub-Mark-32px.png ├── FodyWeavers.xml ├── Models │ ├── DynamicEventData.cs │ ├── FateData.cs │ ├── WorldData.cs │ ├── Template.cs │ ├── InstanceData.cs │ ├── ItemName.cs │ └── TelemetryData.cs ├── Network │ ├── Structures │ │ ├── Materia.cs │ │ ├── IMarketBoardPurchase.cs │ │ ├── WorldVisitQueue.cs │ │ ├── IMarketBoardPurchaseHandler.cs │ │ ├── MarketBoardPurchase.cs │ │ ├── IMarketBoardHistory.cs │ │ ├── IMarketTaxRates.cs │ │ ├── MarketBoardItemRequest.cs │ │ ├── Examine.cs │ │ ├── MarketBoardPurchaseHandler.cs │ │ ├── IMarketBoardCurrentOfferings.cs │ │ ├── MarketTaxRates.cs │ │ └── MarketBoardHistory.cs │ ├── Handler │ │ ├── AbstractHandler.cs │ │ ├── QueueHandler.cs │ │ ├── FishingHandler.cs │ │ └── MarketBoardHandler.cs │ ├── Universalis │ │ ├── Types │ │ │ ├── UniversalisItemMateria.cs │ │ │ ├── UniversalisQueryResponse.cs │ │ │ ├── UniversalisTaxUploadRequest.cs │ │ │ ├── UniversalisItemListingsUploadRequest.cs │ │ │ ├── UniversalisItemUploadRequest.cs │ │ │ ├── UniversalisItemListingDeleteRequest.cs │ │ │ ├── UniversalisTaxData.cs │ │ │ ├── UniversalisHistoryEntry.cs │ │ │ └── UniversalisItemListingsEntry.cs │ │ ├── Client.cs │ │ └── Api.cs │ ├── Packet.cs │ └── State.cs ├── DTO │ ├── BaseDTO.cs │ ├── FishBiteDTO.cs │ ├── InitZoneDTO.cs │ ├── MatchAlertDTO.cs │ ├── TreasureResultDTO.cs │ ├── FateWatchListChangedDTO.cs │ ├── TreasureSpotDTO.cs │ ├── FateDTO.cs │ ├── MiniCactpotDTO.cs │ ├── QueueDTO.cs │ ├── MarketBoardItemListingCountDTO.cs │ ├── DynamicEventDTO.cs │ ├── MarketBoardItemListingDTO.cs │ ├── GearsetDTO.cs │ └── CompanyVoyageStatusDTO.cs ├── GlobalSuppressions.cs ├── Utils │ ├── FateManager.cs │ ├── BindingTarget.cs │ ├── Log.cs │ ├── ParsePlugin.cs │ ├── Telemetry.cs │ ├── Helper.cs │ ├── Output.cs │ └── Request.cs ├── data │ ├── patch.json │ ├── template.json │ ├── type.json │ └── roulette.json ├── ViewModels │ └── TelemetrySetting.cs ├── Views │ ├── License.xaml.cs │ ├── OverrideConfirm.xaml.cs │ ├── OverrideConfirm.xaml │ ├── License.xaml │ ├── TelemetrySetting.xaml.cs │ └── TelemetrySetting.xaml ├── Cafe.Matcha.crproj ├── Config.cs ├── MatchaInit.cs ├── Data.cs ├── Telemetry │ ├── Fate.cs │ └── Npc.cs └── Cafe.Matcha.csproj ├── utils ├── lib │ ├── opcode.mjs │ └── csv.mjs ├── package.json └── update-opcode.mjs ├── README.zh_CN.md ├── Cafe.Matcha.Packer ├── Cafe.Matcha.Packer.csproj └── Program.cs ├── Directory.Build.props ├── stylecop.json ├── README.md ├── Cafe.Matcha.sln ├── .github └── workflows │ └── build.yml ├── StyleCop.ruleset └── .gitignore /Cafe.Matcha/Constant/.gitignore: -------------------------------------------------------------------------------- 1 | Secret.Local.cs -------------------------------------------------------------------------------- /Cafe.Matcha/GitHub-Mark-32px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thewakingsands/matcha/HEAD/Cafe.Matcha/GitHub-Mark-32px.png -------------------------------------------------------------------------------- /utils/lib/opcode.mjs: -------------------------------------------------------------------------------- 1 | export function formatOpcode(num) { 2 | return num.toString(16).padStart(4, '0') 3 | } 4 | 5 | export function parseOpcode(text) { 6 | return parseInt(text, 16) 7 | } 8 | -------------------------------------------------------------------------------- /utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "csv-parse": "^5.3.0" 4 | }, 5 | "prettier": { 6 | "singleQuote": true, 7 | "semi": false, 8 | "trailingComma": "none" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Cafe.Matcha/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /README.zh_CN.md: -------------------------------------------------------------------------------- 1 | # Cafe.Matcha 2 | 3 | 抹茶 (Matcha) 是一个提供 F.A.T.E.、副本匹配、区域切换等游戏内消息提醒的 ACT 插件。和 [抹茶悬浮窗](https://github.com/zhyupe/matcha-overlay) 一同使用时,同时具有市场版查询、装备比较、宝图定位、仙人微彩预测等功能。 4 | 5 | 抹茶 (Matcha) 的名称来源于 Match'a(Match 为匹配、比赛)。本项目起初专注于匹配相关内容的提示。 6 | 7 | 目前抹茶仅提供中文界面,且仅对国服提供更新支持。在更新相关 opcode 后本插件应当能在国际服正常工作。同时本插件欢迎国际化相关的代码贡献。 8 | -------------------------------------------------------------------------------- /Cafe.Matcha/Constant/Region.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Constant 5 | { 6 | public enum Region 7 | { 8 | Global, 9 | China, 10 | Korea 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Cafe.Matcha/Constant/FishEventBiteType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Constant 5 | { 6 | internal enum FishEventBiteType 7 | { 8 | Light = 292, 9 | Medium = 293, 10 | Big = 294 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Cafe.Matcha.Packer/Cafe.Matcha.Packer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net8.0 4 | Exe 5 | true 6 | ..\bin\ 7 | false 8 | 9 | -------------------------------------------------------------------------------- /Cafe.Matcha/Constant/FishEventType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Constant 5 | { 6 | internal enum FishEventType 7 | { 8 | Cast = 1, 9 | Hook = 2, 10 | End = 3, 11 | Bite = 5 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Cafe.Matcha/Constant/RequestType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Constant 5 | { 6 | public enum RequestType 7 | { 8 | Get = 1, 9 | Form = 2, 10 | JSON = 3, 11 | Multipart = 4 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Cafe.Matcha/Models/DynamicEventData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Models 5 | { 6 | using Newtonsoft.Json; 7 | 8 | public class DynamicEventData 9 | { 10 | [JsonProperty("name")] 11 | public ItemName Name; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(SolutionDir)StyleCop.ruleset 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Cafe.Matcha/Constant/TreasureShiftingWheelResultType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Constant 5 | { 6 | internal enum TreasureShiftingWheelResultType 7 | { 8 | Low = 191, 9 | Medium = 192, 10 | High = 193, 11 | Shift = 194, 12 | Special = 195, 13 | End = 196 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Structures/Materia.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Network.Structures 5 | { 6 | using Newtonsoft.Json; 7 | public class Materia 8 | { 9 | [JsonProperty("type")] 10 | public int Type { get; internal set; } 11 | 12 | [JsonProperty("tier")] 13 | public int Tier { get; internal set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /utils/lib/csv.mjs: -------------------------------------------------------------------------------- 1 | import { parse } from 'csv-parse/sync' 2 | 3 | export function readCsv(input, fields, { header = 1, skip = 3 } = {}) { 4 | const lines = parse(input, { 5 | skip_empty_lines: true 6 | }) 7 | 8 | if (!Array.isArray(fields)) { 9 | fields = lines[header] 10 | } 11 | 12 | return lines.slice(skip).map(line => fields.reduce((obj, field, i) => { 13 | obj[`$${i}`] = line[i] 14 | if (field) { 15 | obj[field] = line[i] 16 | } 17 | return obj 18 | }, { _: line })) 19 | } -------------------------------------------------------------------------------- /Cafe.Matcha/Constant/Secret.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Constant 5 | { 6 | internal static partial class Secret 7 | { 8 | public static string TelemetryRoot = ""; 9 | public static string UniversalisKey = ""; 10 | 11 | public static string TelemetryFate = ""; 12 | public static string TelemetryNpc = ""; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Cafe.Matcha/Constant/ActorControlType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Constant 5 | { 6 | internal enum ActorControlType : ushort 7 | { 8 | SetStatus = 2, 9 | DefeatMsg = 6, 10 | TreasureSpot = 84, 11 | DirectorUpdate = 109, 12 | FishingBaitChange = 325, 13 | FateStart = 2370, 14 | FateEnd = 2357, 15 | FateProgress = 2364 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Cafe.Matcha/Constant/LogType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Constant 5 | { 6 | public enum LogType 7 | { 8 | None, 9 | Universalis, 10 | LogLine, 11 | State, 12 | Event, 13 | 14 | #if DEBUG 15 | Request, 16 | Telemetry, 17 | ActorControlSelf, 18 | InvalidPacket, 19 | RawPacket, 20 | Debug1, 21 | #endif 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Cafe.Matcha/DTO/BaseDTO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.DTO 5 | { 6 | using Cafe.Matcha.Constant; 7 | using Newtonsoft.Json; 8 | 9 | internal abstract class BaseDTO 10 | { 11 | [JsonIgnore] 12 | public abstract EventType EventType { get; } 13 | 14 | public virtual string ToJSON() 15 | { 16 | return JsonConvert.SerializeObject(this); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Cafe.Matcha/Models/FateData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Models 5 | { 6 | using Newtonsoft.Json; 7 | 8 | public class FateData 9 | { 10 | [JsonProperty("name")] 11 | public ItemName Name; 12 | 13 | [JsonProperty("level")] 14 | public int Level; 15 | 16 | [JsonProperty("patch")] 17 | public int Patch; 18 | 19 | [JsonProperty("location")] 20 | public int Location; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /stylecop.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", 3 | "settings": { 4 | "documentationRules": { 5 | "companyName": "FFCafe", 6 | "copyrightText": "Copyright (c) {companyName}. All rights reserved.\nLicensed under the {licenseName} license. See {licenseFile} file in the project root for full license information.", 7 | "xmlHeader": false, 8 | "variables": { 9 | "licenseName": "AGPL-3.0", 10 | "licenseFile": "LICENSE" 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Handler/AbstractHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Network.Handler 5 | { 6 | using System; 7 | using Cafe.Matcha.DTO; 8 | 9 | internal abstract class AbstractHandler 10 | { 11 | protected Action fireEvent; 12 | protected AbstractHandler(Action fireEvent) 13 | { 14 | this.fireEvent = fireEvent; 15 | } 16 | 17 | public abstract bool Handle(Packet packet); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Universalis/Types/UniversalisItemMateria.cs: -------------------------------------------------------------------------------- 1 | namespace Cafe.Matcha.Network.Universalis 2 | { 3 | using Newtonsoft.Json; 4 | 5 | /// 6 | /// A Universalis API structure. 7 | /// 8 | internal class UniversalisItemMateria 9 | { 10 | /// 11 | /// Gets or sets the item slot ID. 12 | /// 13 | [JsonProperty("slotID")] 14 | public int SlotId { get; set; } 15 | 16 | /// 17 | /// Gets or sets the materia ID. 18 | /// 19 | [JsonProperty("materiaID")] 20 | public int MateriaId { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cafe.Matcha 2 | 3 | Matcha (抹茶) is an ACT plugin that provides notifications for in-game events such as F.A.T.E.s, duty notifications and zone changing. It also has functions like market board querying, gearsets comparison, treasure map locating, and cactpot predictions when it's used together with [Matcha Overlay](https://github.com/zhyupe/matcha-overlay). 4 | 5 | The name of Matcha is from Match'a, with the project initially focusing on matching events. 6 | 7 | At this time, Matcha only provides up-to-date support for the CN server and only available in Chinese. It should be working in the Global server with proper opcodes filled, and I18n related contributions are welcomed. -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Universalis/Types/UniversalisQueryResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Cafe.Matcha.Network.Universalis 2 | { 3 | using Newtonsoft.Json; 4 | 5 | internal class UniversalisItem 6 | { 7 | [JsonProperty("pricePerUnit")] 8 | public int PricePerUint; 9 | 10 | [JsonProperty("worldName")] 11 | public string WorldName; 12 | 13 | [JsonProperty("quantity")] 14 | public int Quantity; 15 | 16 | [JsonProperty("hq")] 17 | public bool Hq; 18 | } 19 | 20 | internal class UniversalisQueryResponse 21 | { 22 | [JsonProperty("listings")] 23 | public UniversalisItem[] ListingItems; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Cafe.Matcha/DTO/FishBiteDTO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.DTO 5 | { 6 | using Cafe.Matcha.Constant; 7 | using Newtonsoft.Json; 8 | 9 | internal class FishBiteDTO : BaseDTO 10 | { 11 | public override EventType EventType 12 | { 13 | get 14 | { 15 | return EventType.FishBite; 16 | } 17 | } 18 | 19 | [JsonProperty("type")] 20 | public int Type; 21 | 22 | [JsonProperty("time")] 23 | public long Time; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Cafe.Matcha/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | // This file is used by Code Analysis to maintain SuppressMessage 5 | // attributes that are applied to this project. 6 | // Project-level suppressions either have no target or are given 7 | // a specific target and scoped to a namespace, type, member, etc. 8 | 9 | using System.Diagnostics.CodeAnalysis; 10 | 11 | [assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:File should have header", Justification = "<挂起>", Scope = "namespace", Target = "~N:Cafe.Matcha.Network.Universalis")] 12 | -------------------------------------------------------------------------------- /Cafe.Matcha/DTO/InitZoneDTO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.DTO 5 | { 6 | using Cafe.Matcha.Constant; 7 | using Newtonsoft.Json; 8 | 9 | internal class InitZoneDTO : BaseDTO 10 | { 11 | public override EventType EventType 12 | { 13 | get 14 | { 15 | return EventType.InitZone; 16 | } 17 | } 18 | 19 | [JsonProperty("zone")] 20 | public int Zone; 21 | 22 | [JsonProperty("instance")] 23 | public int Instance; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Cafe.Matcha/DTO/MatchAlertDTO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.DTO 5 | { 6 | using Cafe.Matcha.Constant; 7 | using Newtonsoft.Json; 8 | 9 | internal class MatchAlertDTO : BaseDTO 10 | { 11 | public override EventType EventType 12 | { 13 | get 14 | { 15 | return EventType.MatchAlert; 16 | } 17 | } 18 | 19 | [JsonProperty("roulette")] 20 | public int Roulette; 21 | 22 | [JsonProperty("instance")] 23 | public int Instance; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Cafe.Matcha/DTO/TreasureResultDTO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.DTO 5 | { 6 | using Cafe.Matcha.Constant; 7 | using Newtonsoft.Json; 8 | 9 | internal class TreasureResultDTO : BaseDTO 10 | { 11 | public override EventType EventType 12 | { 13 | get 14 | { 15 | return EventType.TreasureResult; 16 | } 17 | } 18 | 19 | [JsonProperty("value")] 20 | public string Value; 21 | 22 | [JsonProperty("round")] 23 | public int Round; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Cafe.Matcha/DTO/FateWatchListChangedDTO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.DTO 5 | { 6 | using Cafe.Matcha.Constant; 7 | using Newtonsoft.Json; 8 | 9 | internal class FateWatchListChangedDTO : BaseDTO 10 | { 11 | public override EventType EventType 12 | { 13 | get 14 | { 15 | return EventType.FateWatchListChanged; 16 | } 17 | } 18 | 19 | [JsonProperty("world")] 20 | public uint World; 21 | 22 | [JsonProperty("fates")] 23 | public int[] Fates; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Cafe.Matcha/Models/WorldData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Models 5 | { 6 | using Newtonsoft.Json; 7 | 8 | public class WorldData 9 | { 10 | [JsonProperty("name")] 11 | public string LocalName; 12 | [JsonProperty("name_en")] 13 | public string EnglishName; 14 | [JsonProperty("dc")] 15 | public string LocalDataCenter; 16 | [JsonProperty("dc_en")] 17 | public string EnglishDataCenter; 18 | 19 | public override string ToString() 20 | { 21 | return LocalName; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Cafe.Matcha/Models/Template.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Models 5 | { 6 | using System.Collections.Generic; 7 | using Cafe.Matcha.Utils; 8 | using Newtonsoft.Json; 9 | 10 | public class Template : BindingTarget 11 | { 12 | public string LocalName 13 | { 14 | get 15 | { 16 | return Name.ToString(); 17 | } 18 | } 19 | 20 | [JsonProperty("name")] 21 | public ItemName Name { get; set; } 22 | 23 | [JsonProperty("fate")] 24 | public List Fates = new List(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Cafe.Matcha/DTO/TreasureSpotDTO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.DTO 5 | { 6 | using Cafe.Matcha.Constant; 7 | using Newtonsoft.Json; 8 | 9 | internal class TreasureSpotDTO : BaseDTO 10 | { 11 | public override EventType EventType 12 | { 13 | get 14 | { 15 | return EventType.TreasureSpot; 16 | } 17 | } 18 | 19 | [JsonProperty("item")] 20 | public int Item; 21 | 22 | [JsonProperty("location")] 23 | public int Location; 24 | 25 | [JsonProperty("isNew")] 26 | public bool IsNew; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Cafe.Matcha/Constant/EventType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Constant 5 | { 6 | // WARNING: The order CANNOT be changed. ONLY append to this list. 7 | public enum EventType 8 | { 9 | None = 0, 10 | Fate, 11 | 12 | MatchAlert, 13 | InitZone, 14 | 15 | FishBite, 16 | MarketBoardItemListing, 17 | MarketBoardItemListingCount, 18 | 19 | MiniCactpot, 20 | Gearset, 21 | TreasureSpot, 22 | TreasureResult, 23 | CompanyVoyageStatus, 24 | 25 | DynamicEvent, 26 | FateWatchListChanged, 27 | Queue, 28 | FishCast 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Cafe.Matcha/DTO/FateDTO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.DTO 5 | { 6 | using Cafe.Matcha.Constant; 7 | using Newtonsoft.Json; 8 | 9 | internal class FateDTO : BaseDTO 10 | { 11 | public override EventType EventType 12 | { 13 | get 14 | { 15 | return EventType.Fate; 16 | } 17 | } 18 | 19 | [JsonProperty("type")] 20 | public string Type; 21 | 22 | [JsonProperty("fate")] 23 | public int Fate; 24 | 25 | [JsonProperty("progress")] 26 | public int Progress = 0; 27 | 28 | [JsonProperty("extra")] 29 | public int Extra = 0; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Cafe.Matcha/DTO/MiniCactpotDTO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.DTO 5 | { 6 | using Cafe.Matcha.Constant; 7 | using Newtonsoft.Json; 8 | 9 | internal class MiniCactpotDTO : BaseDTO 10 | { 11 | public override EventType EventType 12 | { 13 | get 14 | { 15 | return EventType.MiniCactpot; 16 | } 17 | } 18 | 19 | [JsonProperty("isNewGame")] 20 | public bool IsNewGame; 21 | 22 | [JsonProperty("x")] 23 | public int X; 24 | 25 | [JsonProperty("y")] 26 | public int Y; 27 | 28 | [JsonProperty("value")] 29 | public int Value; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Cafe.Matcha/DTO/QueueDTO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.DTO 5 | { 6 | using Cafe.Matcha.Constant; 7 | using Newtonsoft.Json; 8 | 9 | internal class QueueDTO : BaseDTO 10 | { 11 | public override EventType EventType 12 | { 13 | get 14 | { 15 | return EventType.Queue; 16 | } 17 | } 18 | 19 | [JsonProperty("type")] 20 | public string Type; 21 | 22 | [JsonProperty("stage")] 23 | public string Stage; 24 | 25 | [JsonProperty("order")] 26 | public uint Order = 0; 27 | 28 | [JsonProperty("time")] 29 | public uint Time = 0; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Cafe.Matcha/Models/InstanceData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Models 5 | { 6 | using Newtonsoft.Json; 7 | 8 | public class InstanceData 9 | { 10 | [JsonProperty("name")] 11 | public ItemName Name; 12 | 13 | [JsonProperty("type")] 14 | public int Type; 15 | 16 | [JsonProperty("level")] 17 | public int Level; 18 | 19 | [JsonProperty("levelSync")] 20 | public int LevelSync; 21 | 22 | [JsonProperty("item")] 23 | public int ItemLevel; 24 | 25 | [JsonProperty("itemSync")] 26 | public int ItemLevelSync; 27 | 28 | [JsonProperty("memberType")] 29 | public int MemberType; 30 | } 31 | } -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Structures/IMarketBoardPurchase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Network.Structures 5 | { 6 | /// 7 | /// An interface that represents market board purchase information. This message is received from the 8 | /// server when a purchase is made at a market board. 9 | /// 10 | public interface IMarketBoardPurchase 11 | { 12 | /// 13 | /// Gets the item ID of the item that was purchased. 14 | /// 15 | uint CatalogId { get; } 16 | 17 | /// 18 | /// Gets the quantity of the item that was purchased. 19 | /// 20 | uint ItemQuantity { get; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Cafe.Matcha/DTO/MarketBoardItemListingCountDTO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.DTO 5 | { 6 | using System; 7 | using Cafe.Matcha.Constant; 8 | using Newtonsoft.Json; 9 | 10 | internal class MarketBoardItemListingCountDTO : BaseDTO 11 | { 12 | public override EventType EventType 13 | { 14 | get 15 | { 16 | return EventType.MarketBoardItemListingCount; 17 | } 18 | } 19 | 20 | [JsonProperty("item")] 21 | public int Item; 22 | 23 | [JsonProperty("world")] 24 | public int World = 0; 25 | 26 | [JsonProperty("count")] 27 | [Obsolete("Count is not used in overlay and difficult to obtain after 7.0")] 28 | public int Count = 0; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Universalis/Types/UniversalisTaxUploadRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Cafe.Matcha.Network.Universalis 2 | { 3 | using Newtonsoft.Json; 4 | 5 | /// 6 | /// A Universalis API structure. 7 | /// 8 | internal class UniversalisTaxUploadRequest 9 | { 10 | /// 11 | /// Gets or sets the uploader's ID. 12 | /// 13 | [JsonProperty("uploaderID")] 14 | public string UploaderId { get; set; } 15 | 16 | /// 17 | /// Gets or sets the world to retrieve data from. 18 | /// 19 | [JsonProperty("worldID")] 20 | public uint WorldId { get; set; } 21 | 22 | /// 23 | /// Gets or sets tax data for each city's market. 24 | /// 25 | [JsonProperty("marketTaxRates")] 26 | public UniversalisTaxData TaxData { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Cafe.Matcha/Utils/FateManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Utils 5 | { 6 | using System.Collections.Generic; 7 | using System.IO; 8 | using Newtonsoft.Json; 9 | 10 | internal class FateManager 11 | { 12 | public static List Load(string fileName) 13 | { 14 | try 15 | { 16 | string content = File.ReadAllText(fileName); 17 | return JsonConvert.DeserializeObject>(content); 18 | } 19 | catch 20 | { 21 | return null; 22 | } 23 | } 24 | 25 | public static void Save(string fileName, IList fates) 26 | { 27 | File.WriteAllText(fileName, JsonConvert.SerializeObject(fates, Formatting.Indented)); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Cafe.Matcha/data/patch.json: -------------------------------------------------------------------------------- 1 | { 2 | "2": { 3 | "chs": "重生之境", 4 | "en": "A Realm Reborn", 5 | "ja": "新生エオルゼア", 6 | "de": "A Realm Reborn", 7 | "fr": "A Realm Reborn" 8 | }, 9 | "3": { 10 | "chs": "苍穹之禁城", 11 | "en": "Heavensward", 12 | "ja": "蒼天のイシュガルド", 13 | "de": "Heavensward", 14 | "fr": "Heavensward" 15 | }, 16 | "4": { 17 | "chs": "红莲之狂潮", 18 | "en": "Stormblood", 19 | "ja": "紅蓮のリベレーター", 20 | "de": "Stormblood", 21 | "fr": "Stormblood" 22 | }, 23 | "5": { 24 | "chs": "暗影之逆焰", 25 | "en": "Shadowbringers", 26 | "ja": "漆黒のヴィランズ", 27 | "de": "Shadowbringers", 28 | "fr": "Shadowbringers" 29 | }, 30 | "6": { 31 | "chs": "晓月之终途", 32 | "en": "Endwalker", 33 | "ja": "暁月のフィナーレ", 34 | "de": "Endwalker", 35 | "fr": "Endwalker" 36 | }, 37 | "7": { 38 | "chs": "金曦之遗辉", 39 | "en": "Dawntrail", 40 | "ja": "黄金のレガシー", 41 | "de": "Dawntrail", 42 | "fr": "Dawntrail" 43 | } 44 | } -------------------------------------------------------------------------------- /Cafe.Matcha/ViewModels/TelemetrySetting.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.ViewModels 5 | { 6 | using System.Windows; 7 | using Cafe.Matcha.Utils; 8 | 9 | internal class TelemetrySetting : BindingTarget 10 | { 11 | public bool Enabled { get; set; } = true; 12 | public bool IsInit { get; set; } = false; 13 | 14 | public Visibility CheckboxVisibility 15 | { 16 | get 17 | { 18 | return IsInit ? Visibility.Hidden : Visibility.Visible; 19 | } 20 | } 21 | 22 | public string OkText 23 | { 24 | get 25 | { 26 | return IsInit ? "同意" : "确认"; 27 | } 28 | } 29 | 30 | public string CancelText 31 | { 32 | get 33 | { 34 | return IsInit ? "拒绝" : "取消"; 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Cafe.Matcha/Views/License.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Views 5 | { 6 | using System; 7 | using System.Diagnostics; 8 | using System.Windows; 9 | using Cafe.Matcha.Utils; 10 | 11 | public partial class License : Window 12 | { 13 | public License() 14 | { 15 | InitializeComponent(); 16 | Title = "授权提示 - " + Data.Title; 17 | } 18 | 19 | private void BOK_Click(object sender, RoutedEventArgs e) 20 | { 21 | Close(); 22 | } 23 | 24 | private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) 25 | { 26 | Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri)); 27 | e.Handled = true; 28 | } 29 | 30 | private void Window_SourceInitialized(object sender, EventArgs e) 31 | { 32 | Helper.SetDialog(this); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Cafe.Matcha/DTO/DynamicEventDTO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.DTO 5 | { 6 | using Cafe.Matcha.Constant; 7 | using Newtonsoft.Json; 8 | 9 | internal class DynamicEventDTO : BaseDTO 10 | { 11 | public override EventType EventType 12 | { 13 | get 14 | { 15 | return EventType.DynamicEvent; 16 | } 17 | } 18 | 19 | [JsonProperty("zone")] 20 | public int Zone = 0; 21 | 22 | [JsonProperty("event")] 23 | public int Event; 24 | 25 | [JsonProperty("participants")] 26 | public int Participants = 0; 27 | 28 | [JsonProperty("stage")] 29 | public int Stage = 0; 30 | 31 | [JsonProperty("progress")] 32 | public int Progress = 0; 33 | 34 | [JsonProperty("nextStage")] 35 | public uint NextStage; 36 | 37 | [JsonProperty("countdown")] 38 | public int Countdown; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Universalis/Types/UniversalisItemListingsUploadRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Cafe.Matcha.Network.Universalis 2 | { 3 | using System.Collections.Generic; 4 | using Newtonsoft.Json; 5 | 6 | /// 7 | /// A Universalis API structure. 8 | /// 9 | internal class UniversalisItemListingsUploadRequest 10 | { 11 | /// 12 | /// Gets or sets the world ID. 13 | /// 14 | [JsonProperty("worldID")] 15 | public uint WorldId { get; set; } 16 | 17 | /// 18 | /// Gets or sets the item ID. 19 | /// 20 | [JsonProperty("itemID")] 21 | public uint ItemId { get; set; } 22 | 23 | /// 24 | /// Gets or sets the list of available items. 25 | /// 26 | [JsonProperty("listings")] 27 | public List Listings { get; set; } 28 | 29 | /// 30 | /// Gets or sets the uploader ID. 31 | /// 32 | [JsonProperty("uploaderID")] 33 | public string UploaderId { get; set; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Cafe.Matcha/DTO/MarketBoardItemListingDTO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.DTO 5 | { 6 | using System.Collections.Generic; 7 | using Cafe.Matcha.Constant; 8 | using Newtonsoft.Json; 9 | 10 | internal class MarketBoardItemListingItem 11 | { 12 | [JsonProperty("price")] 13 | public int Price; 14 | 15 | [JsonProperty("quantity")] 16 | public int Quantity; 17 | 18 | [JsonProperty("hq")] 19 | public bool HQ; 20 | } 21 | 22 | internal class MarketBoardItemListingDTO : BaseDTO 23 | { 24 | public override EventType EventType 25 | { 26 | get 27 | { 28 | return EventType.MarketBoardItemListing; 29 | } 30 | } 31 | 32 | [JsonProperty("item")] 33 | public int Item; 34 | 35 | [JsonProperty("world")] 36 | public int World = 0; 37 | 38 | [JsonProperty("data")] 39 | public IEnumerable Data; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Cafe.Matcha/DTO/GearsetDTO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.DTO 5 | { 6 | using System.Collections.Generic; 7 | using Cafe.Matcha.Constant; 8 | using Cafe.Matcha.Network.Structures; 9 | using Newtonsoft.Json; 10 | 11 | internal class GearsetDTO : BaseDTO 12 | { 13 | public override EventType EventType 14 | { 15 | get 16 | { 17 | return EventType.Gearset; 18 | } 19 | } 20 | 21 | [JsonProperty("self")] 22 | public bool IsSelf; 23 | 24 | [JsonProperty("name")] 25 | public string Name = string.Empty; 26 | 27 | [JsonProperty("slot")] 28 | public int Slot; 29 | 30 | [JsonProperty("item")] 31 | public int Item; 32 | 33 | [JsonProperty("hq")] 34 | public bool HQ; 35 | 36 | [JsonProperty("glamour")] 37 | public int Glamour; 38 | 39 | [JsonProperty("materias")] 40 | public IEnumerable Materias; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Cafe.Matcha/DTO/CompanyVoyageStatusDTO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.DTO 5 | { 6 | using System.Collections.Generic; 7 | using Cafe.Matcha.Constant; 8 | using Newtonsoft.Json; 9 | 10 | internal class CompanyVoyageStatusItem 11 | { 12 | [JsonProperty("returnTime")] 13 | public uint ReturnTime; 14 | 15 | [JsonProperty("maxDistance")] 16 | public int MaxDistance; 17 | 18 | [JsonProperty("name")] 19 | public string Name; 20 | 21 | [JsonProperty("destination")] 22 | public int[] Destination; 23 | } 24 | 25 | internal class CompanyVoyageStatusDTO : BaseDTO 26 | { 27 | public override EventType EventType 28 | { 29 | get 30 | { 31 | return EventType.CompanyVoyageStatus; 32 | } 33 | } 34 | 35 | [JsonProperty("type")] 36 | public string Type; 37 | 38 | [JsonProperty("list")] 39 | public IEnumerable List; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Handler/QueueHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Network.Handler 5 | { 6 | using System; 7 | using Cafe.Matcha.Constant; 8 | using Cafe.Matcha.DTO; 9 | using Cafe.Matcha.Network.Structures; 10 | 11 | internal class QueueHandler : AbstractHandler 12 | { 13 | public QueueHandler(Action fireEvent) : base(fireEvent) 14 | { 15 | } 16 | 17 | public override bool Handle(Packet packet) 18 | { 19 | if (packet.MatchaOpcode == MatchaOpcode.WorldVisitQueue) 20 | { 21 | var data = WorldVisitQueue.Read(packet.GetRawData()); 22 | fireEvent(new QueueDTO() 23 | { 24 | Type = "world-visit", 25 | Stage = data.Stage == 1 ? "waiting" : data.Stage == 2 ? "ready" : data.Stage == 3 ? "done" : "unknown", 26 | Order = data.Order, 27 | Time = data.Time, 28 | }); 29 | 30 | return true; 31 | } 32 | 33 | return false; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Cafe.Matcha/Views/OverrideConfirm.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Views 5 | { 6 | using System.Windows; 7 | using Cafe.Matcha.Utils; 8 | 9 | public partial class OverrideConfirm : Window 10 | { 11 | public bool All { get; set; } = false; 12 | 13 | public OverrideConfirm() 14 | { 15 | InitializeComponent(); 16 | } 17 | 18 | public OverrideConfirm(string content, string title) : this() 19 | { 20 | this.Title = title; 21 | lMain.Content = content; 22 | } 23 | 24 | private void Close(bool dialogResult) 25 | { 26 | DialogResult = dialogResult; 27 | Close(); 28 | } 29 | 30 | private void BYes_Click(object sender, RoutedEventArgs e) 31 | { 32 | Close(true); 33 | } 34 | 35 | private void BNo_Click(object sender, RoutedEventArgs e) 36 | { 37 | Close(false); 38 | } 39 | 40 | private void Window_SourceInitialized(object sender, System.EventArgs e) 41 | { 42 | Helper.SetDialog(this); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Structures/WorldVisitQueue.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Network.Structures 5 | { 6 | using System.IO; 7 | 8 | public class WorldVisitQueue 9 | { 10 | public uint Stage { get; internal set; } 11 | public uint Order { get; internal set; } 12 | public uint Time { get; internal set; } 13 | 14 | /// 15 | /// Read a object from memory. 16 | /// 17 | /// Data to read. 18 | /// A new object. 19 | public static WorldVisitQueue Read(byte[] data) 20 | { 21 | using (var stream = new MemoryStream(data)) 22 | { 23 | using (var reader = new BinaryReader(stream)) 24 | { 25 | var output = new WorldVisitQueue(); 26 | output.Stage = reader.ReadUInt32(); 27 | output.Order = reader.ReadUInt32(); 28 | output.Time = reader.ReadUInt32(); 29 | return output; 30 | } 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Universalis/Types/UniversalisItemUploadRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Cafe.Matcha.Network.Universalis 2 | { 3 | using System.Collections.Generic; 4 | using Newtonsoft.Json; 5 | 6 | /// 7 | /// A Universalis API structure. 8 | /// 9 | internal class UniversalisItemUploadRequest 10 | { 11 | /// 12 | /// Gets or sets the world ID. 13 | /// 14 | [JsonProperty("worldID")] 15 | public uint WorldId { get; set; } 16 | 17 | /// 18 | /// Gets or sets the item ID. 19 | /// 20 | [JsonProperty("itemID")] 21 | public uint ItemId { get; set; } 22 | 23 | /// 24 | /// Gets or sets the list of available items. 25 | /// 26 | [JsonProperty("listings")] 27 | public List Listings { get; set; } 28 | 29 | /// 30 | /// Gets or sets the list of available entries. 31 | /// 32 | [JsonProperty("entries")] 33 | public List Sales { get; set; } 34 | 35 | /// 36 | /// Gets or sets the uploader ID. 37 | /// 38 | [JsonProperty("uploaderID")] 39 | public string UploaderId { get; set; } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Cafe.Matcha/Models/ItemName.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Models 5 | { 6 | using Newtonsoft.Json; 7 | 8 | public class ItemName 9 | { 10 | [JsonProperty("chs")] 11 | public string Chinese = null; 12 | [JsonProperty("en")] 13 | public string English = null; 14 | [JsonProperty("ja")] 15 | public string Japanese = null; 16 | [JsonProperty("de")] 17 | public string German = null; 18 | [JsonProperty("fr")] 19 | public string French = null; 20 | 21 | public override string ToString() 22 | { 23 | switch (Config.Instance.Language) 24 | { 25 | case FFXIV_ACT_Plugin.Common.Language.French: 26 | return French ?? English; 27 | case FFXIV_ACT_Plugin.Common.Language.German: 28 | return German ?? English; 29 | case FFXIV_ACT_Plugin.Common.Language.Japanese: 30 | return Japanese ?? English; 31 | case FFXIV_ACT_Plugin.Common.Language.Chinese: 32 | return Chinese ?? English; 33 | default: 34 | return English; 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Universalis/Types/UniversalisItemListingDeleteRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Cafe.Matcha.Network.Universalis 2 | { 3 | using Newtonsoft.Json; 4 | 5 | /// 6 | /// Request payload for market board purchases. 7 | /// 8 | internal class UniversalisItemListingDeleteRequest 9 | { 10 | /// 11 | /// Gets or sets the object ID of the retainer associated with the sale. 12 | /// 13 | [JsonProperty("retainerID")] 14 | public string RetainerId { get; set; } 15 | 16 | /// 17 | /// Gets or sets the object ID of the item listing. 18 | /// 19 | [JsonProperty("listingID")] 20 | public string ListingId { get; set; } 21 | 22 | /// 23 | /// Gets or sets the quantity of the item that was purchased. 24 | /// 25 | [JsonProperty("quantity")] 26 | public uint Quantity { get; set; } 27 | 28 | /// 29 | /// Gets or sets the unit price of the item. 30 | /// 31 | [JsonProperty("pricePerUnit")] 32 | public uint PricePerUnit { get; set; } 33 | 34 | /// 35 | /// Gets or sets the uploader ID. 36 | /// 37 | [JsonProperty("uploaderID")] 38 | public string UploaderId { get; set; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Cafe.Matcha/Utils/BindingTarget.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Utils 5 | { 6 | using System.Collections.Generic; 7 | using System.Collections.ObjectModel; 8 | using System.Collections.Specialized; 9 | using System.ComponentModel; 10 | 11 | public class BindingTarget : INotifyPropertyChanged 12 | { 13 | protected void EmitPropertyChanged(string propertyName) 14 | { 15 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 16 | } 17 | 18 | public event PropertyChangedEventHandler PropertyChanged; 19 | } 20 | 21 | public class StaticBindingTarget : BindingTarget where T : new() 22 | { 23 | public static T Instance { get; } = new T(); 24 | } 25 | 26 | public class ListBindingTarget : ObservableCollection 27 | { 28 | public ListBindingTarget() : base() { } 29 | public ListBindingTarget(List list) : base(list) { } 30 | public ListBindingTarget(IEnumerable collection) : base(collection) { } 31 | 32 | public void EmitCollectionChanged(NotifyCollectionChangedEventArgs e) 33 | { 34 | OnCollectionChanged(e); 35 | } 36 | 37 | public void EmitPropertyChanged(PropertyChangedEventArgs e) 38 | { 39 | OnPropertyChanged(e); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Cafe.Matcha/Views/OverrideConfirm.xaml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 22 | 23 | -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Universalis/Types/UniversalisTaxData.cs: -------------------------------------------------------------------------------- 1 | namespace Cafe.Matcha.Network.Universalis 2 | { 3 | using Newtonsoft.Json; 4 | 5 | /// 6 | /// A Universalis API structure. 7 | /// 8 | internal class UniversalisTaxData 9 | { 10 | /// 11 | /// Gets or sets Limsa Lominsa's current tax rate. 12 | /// 13 | [JsonProperty("limsaLominsa")] 14 | public uint LimsaLominsa { get; set; } 15 | 16 | /// 17 | /// Gets or sets Gridania's current tax rate. 18 | /// 19 | [JsonProperty("gridania")] 20 | public uint Gridania { get; set; } 21 | 22 | /// 23 | /// Gets or sets Ul'dah's current tax rate. 24 | /// 25 | [JsonProperty("uldah")] 26 | public uint Uldah { get; set; } 27 | 28 | /// 29 | /// Gets or sets Ishgard's current tax rate. 30 | /// 31 | [JsonProperty("ishgard")] 32 | public uint Ishgard { get; set; } 33 | 34 | /// 35 | /// Gets or sets Kugane's current tax rate. 36 | /// 37 | [JsonProperty("kugane")] 38 | public uint Kugane { get; set; } 39 | 40 | /// 41 | /// Gets or sets The Crystarium's current tax rate. 42 | /// 43 | [JsonProperty("crystarium")] 44 | public uint Crystarium { get; set; } 45 | 46 | /// 47 | /// Gets or sets Old Sharlayan's current tax rate. 48 | /// 49 | [JsonProperty("sharlayan")] 50 | public uint Sharlayan { get; set; } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Structures/IMarketBoardPurchaseHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Network.Structures 5 | { 6 | /// 7 | /// An interface that represents market board purchase information. This message is sent from the 8 | /// client when a purchase is made at a market board. 9 | /// 10 | public interface IMarketBoardPurchaseHandler 11 | { 12 | /// 13 | /// Gets the object ID of the retainer associated with the sale. 14 | /// 15 | ulong RetainerId { get; } 16 | 17 | /// 18 | /// Gets the object ID of the item listing. 19 | /// 20 | ulong ListingId { get; } 21 | 22 | /// 23 | /// Gets the item ID of the item that was purchased. 24 | /// 25 | uint CatalogId { get; } 26 | 27 | /// 28 | /// Gets the quantity of the item that was purchased. 29 | /// 30 | uint ItemQuantity { get; } 31 | 32 | /// 33 | /// Gets the unit price of the item. 34 | /// 35 | uint PricePerUnit { get; } 36 | 37 | /// 38 | /// Gets a value indicating whether the item is HQ. 39 | /// 40 | bool IsHq { get; } 41 | 42 | /// 43 | /// Gets the total tax. 44 | /// 45 | uint TotalTax { get; } 46 | 47 | /// 48 | /// Gets the city ID of the retainer selling the item. 49 | /// 50 | int RetainerCityId { get; } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Structures/MarketBoardPurchase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Network.Structures 5 | { 6 | using System.IO; 7 | 8 | /// 9 | /// Represents market board purchase information. This message is received from the 10 | /// server when a purchase is made at a market board. 11 | /// 12 | public class MarketBoardPurchase : IMarketBoardPurchase 13 | { 14 | private MarketBoardPurchase() 15 | { 16 | } 17 | 18 | /// 19 | /// Gets the item ID of the item that was purchased. 20 | /// 21 | public uint CatalogId { get; private set; } 22 | 23 | /// 24 | /// Gets the quantity of the item that was purchased. 25 | /// 26 | public uint ItemQuantity { get; private set; } 27 | 28 | /// 29 | /// Reads market board purchase information from the struct at the provided pointer. 30 | /// 31 | /// Data to read. 32 | /// An object representing the data read. 33 | public static MarketBoardPurchase Read(byte[] data) 34 | { 35 | using (var stream = new MemoryStream(data)) 36 | { 37 | using (var reader = new BinaryReader(stream)) 38 | { 39 | var output = new MarketBoardPurchase(); 40 | 41 | output.CatalogId = reader.ReadUInt32(); 42 | reader.ReadBytes(0x4); // Padding 43 | output.ItemQuantity = reader.ReadUInt32(); 44 | 45 | return output; 46 | } 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Universalis/Types/UniversalisHistoryEntry.cs: -------------------------------------------------------------------------------- 1 | namespace Cafe.Matcha.Network.Universalis 2 | { 3 | using Newtonsoft.Json; 4 | 5 | /// 6 | /// A Universalis API structure. 7 | /// 8 | internal class UniversalisHistoryEntry 9 | { 10 | /// 11 | /// Gets or sets a value indicating whether the item is HQ or not. 12 | /// 13 | [JsonProperty("hq")] 14 | public bool Hq { get; set; } 15 | 16 | /// 17 | /// Gets or sets the item price per unit. 18 | /// 19 | [JsonProperty("pricePerUnit")] 20 | public uint PricePerUnit { get; set; } 21 | 22 | /// 23 | /// Gets or sets the quantity of items available. 24 | /// 25 | [JsonProperty("quantity")] 26 | public uint Quantity { get; set; } 27 | 28 | /// 29 | /// Gets or sets the name of the buyer. 30 | /// 31 | [JsonProperty("buyerName")] 32 | public string BuyerName { get; set; } 33 | 34 | /// 35 | /// Gets or sets a value indicating whether this item was on a mannequin. 36 | /// 37 | [JsonProperty("onMannequin")] 38 | public bool OnMannequin { get; set; } 39 | 40 | /// 41 | /// Gets or sets the seller ID. 42 | /// 43 | [JsonProperty("sellerID")] 44 | public string SellerId { get; set; } 45 | 46 | /// 47 | /// Gets or sets the buyer ID. 48 | /// 49 | [JsonProperty("buyerID")] 50 | public string BuyerId { get; set; } 51 | 52 | /// 53 | /// Gets or sets the timestamp of the transaction. 54 | /// 55 | [JsonProperty("timestamp")] 56 | public long Timestamp { get; set; } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Structures/IMarketBoardHistory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Network.Structures 5 | { 6 | using System; 7 | using System.Collections.Generic; 8 | 9 | /// 10 | /// An interface that represents the market board history from the game. 11 | /// 12 | public interface IMarketBoardHistory 13 | { 14 | /// 15 | /// Gets the item ID. 16 | /// 17 | uint ItemId { get; } 18 | 19 | /// 20 | /// Gets the list of individual item history listings. 21 | /// 22 | IReadOnlyList HistoryListings { get; } 23 | } 24 | 25 | /// 26 | /// An interface that represents the market board history of a single item from . 27 | /// 28 | public interface IMarketBoardHistoryListing 29 | { 30 | /// 31 | /// Gets the buyer's name. 32 | /// 33 | string BuyerName { get; } 34 | 35 | /// 36 | /// Gets a value indicating whether the item is HQ. 37 | /// 38 | bool IsHq { get; } 39 | 40 | /// 41 | /// Gets a value indicating whether the item is on a mannequin. 42 | /// 43 | bool OnMannequin { get; } 44 | 45 | /// 46 | /// Gets the time of purchase. 47 | /// 48 | DateTime PurchaseTime { get; } 49 | 50 | /// 51 | /// Gets the quantity. 52 | /// 53 | uint Quantity { get; } 54 | 55 | /// 56 | /// Gets the sale price. 57 | /// 58 | uint SalePrice { get; } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Cafe.Matcha/Network/Structures/IMarketTaxRates.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) FFCafe. All rights reserved. 2 | // Licensed under the AGPL-3.0 license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Cafe.Matcha.Network.Structures 5 | { 6 | using System; 7 | 8 | /// 9 | /// An interface that represents the tax rates received by the client when interacting with a retainer vocate. 10 | /// 11 | public interface IMarketTaxRates 12 | { 13 | /// 14 | /// Gets the category of this ResultDialog packet. 15 | /// 16 | uint Category { get; } 17 | 18 | /// 19 | /// Gets the tax rate in Limsa Lominsa. 20 | /// 21 | uint LimsaLominsaTax { get; } 22 | 23 | /// 24 | /// Gets the tax rate in Gridania. 25 | /// 26 | uint GridaniaTax { get; } 27 | 28 | /// 29 | /// Gets the tax rate in Ul'dah. 30 | /// 31 | uint UldahTax { get; } 32 | 33 | /// 34 | /// Gets the tax rate in Ishgard. 35 | /// 36 | uint IshgardTax { get; } 37 | 38 | /// 39 | /// Gets the tax rate in Kugane. 40 | /// 41 | uint KuganeTax { get; } 42 | 43 | /// 44 | /// Gets the tax rate in the Crystarium. 45 | /// 46 | uint CrystariumTax { get; } 47 | 48 | /// 49 | /// Gets the tax rate in the Crystarium. 50 | /// 51 | uint SharlayanTax { get; } 52 | 53 | /// 54 | /// Gets the tax rate in Tuliyollal. 55 | /// 56 | uint TuliyollalTax { get; } 57 | 58 | /// 59 | /// Gets until when these values are valid. 60 | /// 61 | DateTime ValidUntil { get; } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Cafe.Matcha/Views/License.xaml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 本工具当前版本基于 AGPL v3.0 发布,您可以在以下地址取得源码和二进制文件: 18 | 19 | 20 | https://github.com/thewakingsands/matcha 21 | (或主界面右上方的 GitHub 图标) 22 | 23 | 24 | 25 | 本工具免费发布,不对功能提供任何担保,且未通过任何渠道出售。如果您在获取本工具时支付了任何费用,您可能已经上当受骗。 26 | 27 | 28 | 29 | 30 |