Skip to content
This repository has been archived by the owner on Oct 21, 2020. It is now read-only.

Commit

Permalink
Merge pull request #1 from atfinke/3.1
Browse files Browse the repository at this point in the history
3.1 Released
  • Loading branch information
atfinke authored Sep 30, 2017
2 parents 0944021 + d8f6131 commit 7fb2b7b
Show file tree
Hide file tree
Showing 71 changed files with 937 additions and 245 deletions.
Binary file removed Icon.png
Binary file not shown.
30 changes: 21 additions & 9 deletions WKRKit/WKRKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@
149FF8171F362B3D000A5D96 /* WKRKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 149FF8161F362B3D000A5D96 /* WKRKitTests.swift */; };
149FF8191F362B3D000A5D96 /* WKRKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 149FF80B1F362B3D000A5D96 /* WKRKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
14AF1CB81F57C52E000EFC2B /* WKRUIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14AF1CB91F57C52E000EFC2B /* WKRUIKit.framework */; };
14E1B1981F7954A00082F4FA /* WKRKitConstants.plist in Resources */ = {isa = PBXBuildFile; fileRef = 14E1B1971F7954A00082F4FA /* WKRKitConstants.plist */; };
14E6DFAE1F3685B8002755C3 /* WKRPreRaceConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14E6DFAD1F3685B8002755C3 /* WKRPreRaceConfig.swift */; };
14E6DFB01F3685EF002755C3 /* WKRKit+Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14E6DFAF1F3685EF002755C3 /* WKRKit+Array.swift */; };
14E9E16D1F63462500D2CAB4 /* WKRFatalError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14E9E16C1F63462500D2CAB4 /* WKRFatalError.swift */; };
14EB9F461F36825100FF1A9E /* WKRPlayerMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14EB9F451F36825100FF1A9E /* WKRPlayerMessage.swift */; };
14EB9F4A1F3682A000FF1A9E /* WKRGameState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14EB9F491F3682A000FF1A9E /* WKRGameState.swift */; };
14EB9F4C1F3682BE00FF1A9E /* WKRRaceConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14EB9F4B1F3682BE00FF1A9E /* WKRRaceConfig.swift */; };
14EB9F4E1F3682C500FF1A9E /* WKRActiveRace.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14EB9F4D1F3682C500FF1A9E /* WKRActiveRace.swift */; };
14EB9F4E1F3682C500FF1A9E /* WKRRace.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14EB9F4D1F3682C500FF1A9E /* WKRRace.swift */; };
14EB9F501F3682CA00FF1A9E /* WKRGame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14EB9F4F1F3682CA00FF1A9E /* WKRGame.swift */; };
14EB9F521F3682D000FF1A9E /* WKRManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14EB9F511F3682D000FF1A9E /* WKRManager.swift */; };
14EB9F541F3682D600FF1A9E /* WKRManager+Host.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14EB9F531F3682D600FF1A9E /* WKRManager+Host.swift */; };
Expand Down Expand Up @@ -85,14 +86,15 @@
149FF8161F362B3D000A5D96 /* WKRKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKRKitTests.swift; sourceTree = "<group>"; };
149FF8181F362B3D000A5D96 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
14AF1CB91F57C52E000EFC2B /* WKRUIKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WKRUIKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
14E1B1971F7954A00082F4FA /* WKRKitConstants.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = WKRKitConstants.plist; sourceTree = "<group>"; };
14E6DFAD1F3685B8002755C3 /* WKRPreRaceConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKRPreRaceConfig.swift; sourceTree = "<group>"; };
14E6DFAF1F3685EF002755C3 /* WKRKit+Array.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WKRKit+Array.swift"; sourceTree = "<group>"; };
14E6DFB61F3687B5002755C3 /* WKRGetLinks.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = WKRGetLinks.js; path = WKRKit/WKRGetLinks.js; sourceTree = SOURCE_ROOT; };
14E6DFB61F3687B5002755C3 /* WKRGetLinks.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = WKRGetLinks.js; path = "WKRKit/Web Logic/WKRGetLinks.js"; sourceTree = SOURCE_ROOT; };
14E9E16C1F63462500D2CAB4 /* WKRFatalError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKRFatalError.swift; sourceTree = "<group>"; };
14EB9F451F36825100FF1A9E /* WKRPlayerMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKRPlayerMessage.swift; sourceTree = "<group>"; };
14EB9F491F3682A000FF1A9E /* WKRGameState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKRGameState.swift; sourceTree = "<group>"; };
14EB9F4B1F3682BE00FF1A9E /* WKRRaceConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKRRaceConfig.swift; sourceTree = "<group>"; };
14EB9F4D1F3682C500FF1A9E /* WKRActiveRace.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKRActiveRace.swift; sourceTree = "<group>"; };
14EB9F4D1F3682C500FF1A9E /* WKRRace.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKRRace.swift; sourceTree = "<group>"; };
14EB9F4F1F3682CA00FF1A9E /* WKRGame.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKRGame.swift; sourceTree = "<group>"; };
14EB9F511F3682D000FF1A9E /* WKRManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKRManager.swift; sourceTree = "<group>"; };
14EB9F531F3682D600FF1A9E /* WKRManager+Host.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WKRManager+Host.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -131,6 +133,17 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
140192221F7C694F00E67857 /* Constants */ = {
isa = PBXGroup;
children = (
1410DB471F4F53E200F5CAD7 /* WKRArticlesData.plist */,
14E1B1971F7954A00082F4FA /* WKRKitConstants.plist */,
1452B3731F36529300E81FD8 /* WKRKitConstants.swift */,
1452B3751F3652E900E81FD8 /* WKRRaceConstants.swift */,
);
path = Constants;
sourceTree = "<group>";
};
149FF7FE1F362B3D000A5D96 = {
isa = PBXGroup;
children = (
Expand All @@ -154,6 +167,7 @@
isa = PBXGroup;
children = (
149FF80B1F362B3D000A5D96 /* WKRKit.h */,
140192221F7C694F00E67857 /* Constants */,
14E6DFB31F3686EE002755C3 /* Game */,
14E6DFB11F3686B1002755C3 /* Manager */,
14EB9F6F1F3684FC00FF1A9E /* Network */,
Expand Down Expand Up @@ -216,7 +230,7 @@
1497F3191F588EBE001653DE /* WKRReadyStates.swift */,
14EB9F491F3682A000FF1A9E /* WKRGameState.swift */,
14EB9F721F36854700FF1A9E /* WKRVoteInfo.swift */,
14EB9F4D1F3682C500FF1A9E /* WKRActiveRace.swift */,
14EB9F4D1F3682C500FF1A9E /* WKRRace.swift */,
14EB9F4B1F3682BE00FF1A9E /* WKRRaceConfig.swift */,
14E6DFAD1F3685B8002755C3 /* WKRPreRaceConfig.swift */,
);
Expand All @@ -226,12 +240,9 @@
14E6DFB41F368742002755C3 /* Other */ = {
isa = PBXGroup;
children = (
1410DB471F4F53E200F5CAD7 /* WKRArticlesData.plist */,
1452B3731F36529300E81FD8 /* WKRKitConstants.swift */,
1452B3751F3652E900E81FD8 /* WKRRaceConstants.swift */,
14E9E16C1F63462500D2CAB4 /* WKRFatalError.swift */,
14E6DFAF1F3685EF002755C3 /* WKRKit+Array.swift */,
14EB9F651F36833A00FF1A9E /* WKROperation.swift */,
14E9E16C1F63462500D2CAB4 /* WKRFatalError.swift */,
);
path = Other;
sourceTree = "<group>";
Expand Down Expand Up @@ -391,6 +402,7 @@
files = (
1410DB4B1F4F552200F5CAD7 /* WKRGetLinks.js in Resources */,
1410DB481F4F544300F5CAD7 /* WKRArticlesData.plist in Resources */,
14E1B1981F7954A00082F4FA /* WKRKitConstants.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -442,7 +454,7 @@
14EB9F581F3682F200FF1A9E /* WKRManager+PageNavigation.swift in Sources */,
140FCFC31F36547E00FFA84E /* WKRResultsInfo.swift in Sources */,
14EB9F641F36833400FF1A9E /* WKRCodable.swift in Sources */,
14EB9F4E1F3682C500FF1A9E /* WKRActiveRace.swift in Sources */,
14EB9F4E1F3682C500FF1A9E /* WKRRace.swift in Sources */,
14EB9F6C1F36835800FF1A9E /* WKRLinkedPagesFetcher.swift in Sources */,
140FCFCF1F3654FC00FFA84E /* WKRHistory.swift in Sources */,
14EB9F541F3682D600FF1A9E /* WKRManager+Host.swift in Sources */,
Expand Down
29 changes: 29 additions & 0 deletions WKRKit/WKRKit/Constants/WKRKitConstants.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BannedURLFragments</key>
<array>
<string>/wiki/File</string>
<string>org/wiki/Wikipedia:</string>
<string>org/wiki/Special</string>
<string>org/wiki/Portal:</string>
<string>/File:</string>
<string>#/</string>
</array>
<key>BaseURLString</key>
<string>https://en.m.wikipedia.org/wiki</string>
<key>PageTitleCharactersToRemove</key>
<integer>0</integer>
<key>PageTitleStringToReplace</key>
<string> - Wikipedia</string>
<key>QuickRace</key>
<false/>
<key>RandomURLString</key>
<string>https://en.m.wikipedia.org/wiki/Special:Random</string>
<key>Version</key>
<integer>1</integer>
<key>WhatLinksHereURLString</key>
<string>https://en.m.wikipedia.org/w/index.php?title=Special:WhatLinksHere</string>
</dict>
</plist>
182 changes: 182 additions & 0 deletions WKRKit/WKRKit/Constants/WKRKitConstants.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
//
// WKRConstants.swift
// WKRKit
//
// Created by Andrew Finke on 8/5/17.
// Copyright © 2017 Andrew Finke. All rights reserved.
//

import CloudKit
import Foundation

public class WKRKitConstants {

public let version: Int
public static var current = WKRKitConstants()

internal let quickRace: Bool

internal let pageTitleStringToReplace: String
internal let pageTitleCharactersToRemove: Int

internal let baseURLString: String
internal let randomURLString: String
internal let whatLinksHereURLString: String

internal let bannedURLFragments: [String]

init() {
//swiftlint:disable:next line_length
guard let documentsConstantsURL = FileManager.default.documentsDirectory?.appendingPathComponent("WKRKitConstants.plist"),
let documentsConstants = NSDictionary(contentsOf: documentsConstantsURL) as? [String:Any] else {
fatalError()
}

guard let version = documentsConstants["Version"] as? Int else {
fatalError("WKRKitConstants: No Version value")
}
guard let quickRace = documentsConstants["QuickRace"] as? Bool else {
fatalError("WKRKitConstants: No QuickRace value")
}
guard let pageTitleStringToReplace = documentsConstants["PageTitleStringToReplace"] as? String else {
fatalError("WKRKitConstants: No PageTitleStringToReplace value")
}
guard let pageTitleCharactersToRemove = documentsConstants["PageTitleCharactersToRemove"] as? Int else {
fatalError("WKRKitConstants: No PageTitleCharactersToRemove value")
}
guard let baseURLString = documentsConstants["BaseURLString"] as? String else {
fatalError("WKRKitConstants: No BaseURLString value")
}
guard let randomURLString = documentsConstants["RandomURLString"] as? String else {
fatalError("WKRKitConstants: No RandomURLString value")
}
guard let whatLinksHereURLString = documentsConstants["WhatLinksHereURLString"] as? String else {
fatalError("WKRKitConstants: No WhatLinksHereURLString value")
}
guard let bannedURLFragments = documentsConstants["BannedURLFragments"] as? [String] else {
fatalError("WKRKitConstants: No BannedURLFragments value")
}

self.version = version
self.quickRace = quickRace

self.pageTitleStringToReplace = pageTitleStringToReplace
self.pageTitleCharactersToRemove = pageTitleCharactersToRemove

self.baseURLString = baseURLString
self.randomURLString = randomURLString
self.whatLinksHereURLString = whatLinksHereURLString

self.bannedURLFragments = bannedURLFragments
}

static public func updateConstants() {
copyBundledResourcesToDocuments()

let publicDB = CKContainer.default().publicCloudDatabase
let recordID = CKRecordID(recordName: "WKRKitConstantsRecord")

publicDB.fetch(withRecordID: recordID) { record, _ in
guard let record = record else {
return
}

guard let recordConstantsAsset = record["ConstantsFile"] as? CKAsset,
let recordArticlesAsset = record["ArticlesFile"] as? CKAsset,
let recordGetLinksScriptAsset = record["GetLinksScriptFile"] as? CKAsset else {
return
}

copyIfNewer(newConstantsFileURL: recordConstantsAsset.fileURL,
newArticlesFileURL: recordArticlesAsset.fileURL,
newGetLinksScriptFileURL: recordGetLinksScriptAsset.fileURL)
}
}

static private func copyIfNewer(newConstantsFileURL: URL,
newArticlesFileURL: URL,
newGetLinksScriptFileURL: URL) {

guard FileManager.default.fileExists(atPath: newConstantsFileURL.path),
FileManager.default.fileExists(atPath: newArticlesFileURL.path),
FileManager.default.fileExists(atPath: newGetLinksScriptFileURL.path) else {
return
}

guard let newConstants = NSDictionary(contentsOf: newConstantsFileURL),
let newConstantsVersion = newConstants["Version"] as? Int,
let documentsDirectory = FileManager.default.documentsDirectory else {
return
}

let documentsArticlesURL = documentsDirectory.appendingPathComponent("WKRArticlesData.plist")
let documentsConstantsURL = documentsDirectory.appendingPathComponent("WKRKitConstants.plist")
let documentsGetLinksScriptURL = documentsDirectory.appendingPathComponent("WKRGetLinks.js")

var shouldReplaceExisitingConstants = true
if FileManager.default.fileExists(atPath: documentsConstantsURL.path),
let documentsConstants = NSDictionary(contentsOf: documentsConstantsURL),
let documentsConstantsVersions = documentsConstants["Version"] as? Int {

if newConstantsVersion <= documentsConstantsVersions {
shouldReplaceExisitingConstants = false
}
}

if shouldReplaceExisitingConstants {
do {
try? FileManager.default.removeItem(at: documentsArticlesURL)
try FileManager.default.copyItem(at: newArticlesFileURL, to: documentsArticlesURL)

try? FileManager.default.removeItem(at: documentsGetLinksScriptURL)
try FileManager.default.copyItem(at: newGetLinksScriptFileURL, to: documentsGetLinksScriptURL)

try? FileManager.default.removeItem(at: documentsConstantsURL)
try FileManager.default.copyItem(at: newConstantsFileURL, to: documentsConstantsURL)
} catch {
print(error)
}
}

current = WKRKitConstants()
}

static private func copyBundledResourcesToDocuments() {
guard let bundle = Bundle(identifier: "com.andrewfinke.WKRKit"),
let bundledPlistURL = bundle.url(forResource: "WKRKitConstants", withExtension: "plist"),
let bundledArticlesURL = bundle.url(forResource: "WKRArticlesData", withExtension: "plist"),
let bundledGetLinksScriptURL = bundle.url(forResource: "WKRGetLinks", withExtension: "js") else {
fatalError()
}

copyIfNewer(newConstantsFileURL: bundledPlistURL,
newArticlesFileURL: bundledArticlesURL,
newGetLinksScriptFileURL: bundledGetLinksScriptURL)
}

internal func finalArticles() -> [String] {
//swiftlint:disable:next line_length
guard let documentsArticlesURL = FileManager.default.documentsDirectory?.appendingPathComponent("WKRArticlesData.plist"),
let arrayFromURL = NSArray(contentsOf: documentsArticlesURL),
let array = arrayFromURL as? [String] else {
fatalError()
}
return array
}

internal func getLinksScript() -> String {
//swiftlint:disable:next line_length
guard let documentsScriptURL = FileManager.default.documentsDirectory?.appendingPathComponent("WKRGetLinks.js"),
let source = try? String(contentsOf: documentsScriptURL) else {
fatalError()
}
return source
}

}

extension FileManager {
var documentsDirectory: URL? {
return urls(for: .documentDirectory, in: .userDomainMask).first
}
}
19 changes: 10 additions & 9 deletions WKRKit/WKRKit/Game/WKRGame.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation

public class WKRGame {

// MARK: - Closure
// MARK: - Closures

var bonusPointsUpdated: ((Int) -> Void)?

Expand All @@ -30,8 +30,8 @@ public class WKRGame {
internal var raceConfig: WKRRaceConfig?
internal var preRaceConfig: WKRPreRaceConfig?

internal private(set) var activeRace: WKRActiveRace?
internal private(set) var completedRaces = [WKRActiveRace]()
internal private(set) var activeRace: WKRRace?
internal private(set) var completedRaces = [WKRRace]()

public internal(set) var state = WKRGameState.preMatch

Expand All @@ -45,16 +45,16 @@ public class WKRGame {

internal func startRace(with config: WKRRaceConfig) {
raceConfig = config
activeRace = WKRActiveRace(config: config)
activeRace = WKRRace(config: config)
preRaceConfig = nil

if localPlayer.isHost {
bonusTimer?.invalidate()
bonusTimer = Timer.scheduledTimer(withTimeInterval: WKRRaceConstants.bonusPointInterval,
repeats: true) { _ in
self.activeRace?.bonusPoints += WKRRaceConstants.bonusPointReward
if let points = self.activeRace?.bonusPoints {
self.bonusPointsUpdated?(points)
repeats: true) { [weak self] _ in
self?.activeRace?.bonusPoints += WKRRaceConstants.bonusPointReward
if let points = self?.activeRace?.bonusPoints {
self?.bonusPointsUpdated?(points)
}
}
}
Expand All @@ -67,7 +67,8 @@ public class WKRGame {
}

func finishedRace() {
if let race = activeRace {
if var race = activeRace {
race.linkedPagesFetcher = nil
completedRaces.append(race)
}
activeRace = nil
Expand Down
9 changes: 7 additions & 2 deletions WKRKit/WKRKit/Game/WKRGameState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@

import Foundation

/// The state of the game
public enum WKRGameState: Int {
/// Set when first connecting
case preMatch
/// Set in voting
case voting
/// Set when race starts
case race

/// Set when player finds page and/or forfeits
case results
/// Set when host sends final results for a race
case hostResults

/// Set when showing the point totals
case points
}
Loading

0 comments on commit 7fb2b7b

Please sign in to comment.