OSDN Git Service

現在の艦隊をデッキビルダーで開けるようにした
authormasakih <masakih@users.sourceforge.jp>
Sun, 16 Jul 2017 05:47:39 +0000 (14:47 +0900)
committermasakih <masakih@users.sourceforge.jp>
Sun, 16 Jul 2017 05:47:39 +0000 (14:47 +0900)
KCD.xcodeproj/project.pbxproj
KCD/AppDelegate.swift
KCD/Base.lproj/MainMenu.xib
KCD/Deck.swift
KCD/DeckBuilder.swift [new file with mode: 0644]
KCD/DeckBuilderStructure.swift [new file with mode: 0644]
KCD/ServerDataStore.swift
KCD/ja.lproj/MainMenu.strings

index 4e7ecee..5eb0395 100644 (file)
                F4E5FF121E17D6850026868C /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4E5FF111E17D6850026868C /* GameViewController.swift */; };
                F4E5FF141E17F93B0026868C /* BroserWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4E5FF131E17F93B0026868C /* BroserWindowController.swift */; };
                F4E7802E18DC3AF00011BC4C /* LocalData.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = F4E7802C18DC3AF00011BC4C /* LocalData.xcdatamodeld */; };
+               F4EE4AD81F18F43700AD92B4 /* DeckBuilderStructure.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EE4AD71F18F43700AD92B4 /* DeckBuilderStructure.swift */; };
+               F4EE4ADA1F18F66A00AD92B4 /* DeckBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EE4AD91F18F66A00AD92B4 /* DeckBuilder.swift */; };
                F4EFBCA51E7D757E00DE4A58 /* SwiftyJSON.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4EFBCA21E7D439A00DE4A58 /* SwiftyJSON.framework */; };
                F4EFBCA61E7D757E00DE4A58 /* SwiftyJSON.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = F4EFBCA21E7D439A00DE4A58 /* SwiftyJSON.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
                F4F947071D5DBA2D00F95998 /* MapWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4F947091D5DBA2D00F95998 /* MapWindowController.xib */; };
                F4E5FF111E17D6850026868C /* GameViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameViewController.swift; sourceTree = "<group>"; };
                F4E5FF131E17F93B0026868C /* BroserWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BroserWindowController.swift; sourceTree = "<group>"; };
                F4E7802D18DC3AF00011BC4C /* LocalData.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = LocalData.xcdatamodel; sourceTree = "<group>"; };
+               F4EE4AD71F18F43700AD92B4 /* DeckBuilderStructure.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeckBuilderStructure.swift; sourceTree = "<group>"; };
+               F4EE4AD91F18F66A00AD92B4 /* DeckBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeckBuilder.swift; sourceTree = "<group>"; };
                F4EFBCA21E7D439A00DE4A58 /* SwiftyJSON.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftyJSON.framework; path = Carthage/Build/Mac/SwiftyJSON.framework; sourceTree = "<group>"; };
                F4F947061D5DBA1A00F95998 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UITestWindowController.xib; sourceTree = "<group>"; };
                F4F947081D5DBA2D00F95998 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MapWindowController.xib; sourceTree = "<group>"; };
                                F44AA26A1E82AD2E00EED8BE /* NSObjectExtension.swift */,
                                F44775881EF6AAD900287572 /* SakutekiCalculator.swift */,
                                F42546911EF8002E00BE297E /* EquitType.swift */,
+                               F4EE4AD71F18F43700AD92B4 /* DeckBuilderStructure.swift */,
+                               F4EE4AD91F18F66A00AD92B4 /* DeckBuilder.swift */,
                                F4BEEFE21B0CD39B004702B8 /* Transformar&Formatter */,
                                F4C118F318A67B05005D5B25 /* CustomHTTPProtocol */,
                                F47215A11E1F38280083D3BC /* Queue.swift */,
                                F4E5FF141E17F93B0026868C /* BroserWindowController.swift in Sources */,
                                F4CF25BA1E34EB6600C02A66 /* BookmarkManager.swift in Sources */,
                                F44BC7051E2660E4004644E3 /* StoreCreateSlotItemHistoryCommand.swift in Sources */,
+                               F4EE4ADA1F18F66A00AD92B4 /* DeckBuilder.swift in Sources */,
                                F4E5FF061E1523900026868C /* ScreenshotCollectionViewItem.swift in Sources */,
                                F4D3D9551E8544B90085A389 /* StrengthenListItem.swift in Sources */,
                                F44BC6DF1E228770004644E3 /* QuestListCommand.swift in Sources */,
                                F42A8FDE1E40C6DF0099DC1D /* Quest.swift in Sources */,
                                F4B15CBD1E21BA870078CFFC /* CommandRegister.swift in Sources */,
                                F4BDEEB01E72D2D700D689AE /* HistoryTableViewController.swift in Sources */,
+                               F4EE4AD81F18F43700AD92B4 /* DeckBuilderStructure.swift in Sources */,
                                F45FBB921E129BAE000E72B9 /* FleetViewController.swift in Sources */,
                                F4AA59501E1E4D18001667AF /* ShipWindowController.swift in Sources */,
                                F42CFE181E3C12AA000B4F9B /* ScreenshotInformation.swift in Sources */,
index 19a4e99..be8abbf 100644 (file)
@@ -171,6 +171,11 @@ extension AppDelegate {
         windowManager.openDocument(sender)
     }
     
+    @IBAction func openInDeckBuilder(_ sender: Any?) {
+        
+        DeckBuilder().openDeckBuilder()
+    }
+    
     override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
         guard let action = menuItem.action else { return false }
         switch action {
@@ -178,6 +183,8 @@ extension AppDelegate {
             return true
         case Selector.removeDatabaseFile:
             return true
+        case #selector(openInDeckBuilder(_:)):
+            return true
         default:
             return windowManager.validateMenuItem(menuItem)
         }
index fba7e56..4aba4cf 100644 (file)
                                     <action selector="openNewBrowser:" target="-1" id="gnv-IH-H9F"/>
                                 </connections>
                             </menuItem>
+                            <menuItem isSeparatorItem="YES" id="Btg-ej-IXz"/>
+                            <menuItem title="Open in DeckBuilder" id="oGw-ne-id0">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="openInDeckBuilder:" target="494" id="lsj-Oj-nEf"/>
+                                </connections>
+                            </menuItem>
                             <menuItem isSeparatorItem="YES" id="8zj-xF-FZU"/>
                             <menuItem title="Close" keyEquivalent="w" id="73">
                                 <connections>
index ca6e31b..add5c6e 100644 (file)
@@ -65,4 +65,8 @@ extension Deck {
         guard let shipId = shipId(of: index) else { return nil }
         return ship(ofId: shipId)
     }
+    
+    subscript(_ range: CountableClosedRange<Int>) -> [Ship] {
+        return range.flatMap { self[$0] }
+    }
 }
diff --git a/KCD/DeckBuilder.swift b/KCD/DeckBuilder.swift
new file mode 100644 (file)
index 0000000..334e63f
--- /dev/null
@@ -0,0 +1,75 @@
+//
+//  DeckBuilder.swift
+//  KCD
+//
+//  Created by Hori,Masaki on 2017/07/14.
+//  Copyright © 2017年 Hori,Masaki. All rights reserved.
+//
+
+import Cocoa
+
+class DeckBuilder {
+    
+    private let structure: DeckBuilderStructure
+    
+    init() {
+        
+        structure = DeckBuilder.build()
+    }
+    
+    func openDeckBuilder() {
+        
+        // use for encodeURIComponent() of Javascript
+        var characterSet = CharacterSet.alphanumerics
+        characterSet.insert(charactersIn: "-_.!~*'()")
+        
+        let desc = structure.deckDescription
+        Debug.excute(level: .debug) { print(desc as Any) }
+        let ss = "http://kancolle-calc.net/deckbuilder.html?predeck="
+        
+        if let param = desc.addingPercentEncoding(withAllowedCharacters: characterSet),
+            let url = URL(string: ss + param) {
+            
+            NSWorkspace.shared().open(url)
+        }
+    }
+    
+    private static func build() -> DeckBuilderStructure {
+        
+        let fleets = ServerDataStore.default
+            .decksSortedById()
+            .map(buildDeck)
+        let hqLv = ServerDataStore.default.basic()?.level
+        
+        return DeckBuilderStructure(hqLv: hqLv, fleets: fleets)
+    }
+    
+    private static func buildDeck(deck: Deck) -> DBFleet {
+        
+        let ships = deck[0...5].map(buildShip)
+        
+        return DBFleet(ships: ships)
+    }
+    
+    private static func buildShip(ship: Ship) -> DBShip {
+        
+        let items = ship
+            .equippedItem
+            .flatMap { $0 as? SlotItem }
+            .flatMap(buildItem)
+        let exItem = ship.extraItem.map(buildItem)
+        
+        return DBShip(id: ship.master_ship.id,
+                      lv: ship.lv,
+                      luck: ship.lucky_0,
+                      items: items,
+                      exItem: exItem)
+    }
+    
+    private static func buildItem(item: SlotItem) -> DBItem {
+        
+        return DBItem(id: item.master_slotItem.id,
+                      lv: item.level != 0 ? item.level : nil,
+                      aLv: item.alv != 0 ? item.alv : nil)
+    }
+}
diff --git a/KCD/DeckBuilderStructure.swift b/KCD/DeckBuilderStructure.swift
new file mode 100644 (file)
index 0000000..451a115
--- /dev/null
@@ -0,0 +1,103 @@
+//
+//  DeckBuilderStructure.swift
+//  KCD
+//
+//  Created by Hori,Masaki on 2017/07/14.
+//  Copyright © 2017年 Hori,Masaki. All rights reserved.
+//
+
+import Foundation
+
+protocol DeckBuilderDescriptable {
+    var deckDescription: String { get }
+}
+
+struct DeckBuilderStructure {
+    let version: Int = 4
+    let hqLv: Int?
+    let fleets: [DBFleet]
+}
+
+struct DBFleet {
+    let ships: [DBShip]
+}
+
+struct DBShip {
+    let id: Int
+    let lv: Int
+    let luck: Int
+    let items: [DBItem]
+    let exItem: DBItem?
+}
+
+struct DBItem {
+    let id: Int
+    let lv: Int?
+    let aLv: Int?
+}
+
+extension DeckBuilderStructure: DeckBuilderDescriptable {
+    var deckDescription: String {
+        
+        let verStr = "\"version\":\(version)"
+        let fleetStr = zip(1...4, fleets)
+            .map { "\"f\($0.0)\":{\($0.1.deckDescription)}" }
+            .joined(separator: ",")
+        let hqLvStr = hqLv.map { "\"hqlv\":\($0)" }
+        
+        let join = [verStr, fleetStr, hqLvStr]
+            .flatMap { $0 }
+            .joined(separator: ",")
+        
+        return "{\(join)}"
+    }
+}
+
+extension DBFleet: DeckBuilderDescriptable {
+    var deckDescription: String {
+        
+        return zip(1...6, ships)
+            .map { "\"s\($0.0)\":{\($0.1.deckDescription)}" }
+            .joined(separator: ",")
+    }
+}
+
+extension DBShip: DeckBuilderDescriptable {
+    var deckDescription: String {
+        
+        return "\"id\":\"\(id)\",\"lv\":\(lv),\"luck\":\(luck),\"items\":{\(fullItemDesc)}"
+    }
+    
+    private var fullItemDesc: String {
+        
+        switch (items, exDesc) {
+        case let (items, ex?) where items.isEmpty: return ex
+        case let (_, ex?): return "\(itemsDesc),\(ex)"
+        default: return itemsDesc
+        }
+    }
+    
+    private var itemsDesc: String {
+        
+        return zip(1...4, items)
+            .map { "\"i\($0.0)\":{\($0.1.deckDescription)}" }
+            .joined(separator: ",")
+    }
+    
+    private var exDesc: String? {
+        
+        return exItem.map { "\"ix\":{\($0.deckDescription)}" }
+    }
+}
+
+extension DBItem: DeckBuilderDescriptable {
+    var deckDescription: String {
+        
+        switch (lv, aLv) {
+        case let (lv?, aLv?): return "\"id\":\(id),\"rf\":\(lv),\"mas\":\(aLv)"
+        case let (lv?, _): return "\"id\":\(id),\"rf\":\(lv)"
+        case let (_, aLv?): return "\"id\":\(id),\"mas\":\(aLv)"
+        default: return "\"id\":\(id)"
+        }
+    }
+}
index 8a1cbd3..9fb82cd 100644 (file)
@@ -172,7 +172,7 @@ extension ServerDataStore {
         guard let decks = try? objects(with: Deck.entity, predicate: predicate),
             let deck = decks.first
             else { return [] }
-        return (0..<6).flatMap { deck[$0] }
+        return deck[0...5]
     }
     func ship(by shipId: Int) -> Ship? {
         if shipId < 1 { return nil }
index 97a7743..31ba91c 100644 (file)
 "wbG-TI-Ox5.title" = "判定式 (33) - 4";
 "z7j-YG-JPw.title" = "判定式 (33) ...";
 
-
-
-
-
+"oGw-ne-id0.title" = "デッキビルダーで開く";