2 // GameViewController.swift
5 // Created by Hori,Masaki on 2016/12/31.
6 // Copyright © 2016年 Hori,Masaki. All rights reserved.
13 final class GameViewController: NSViewController {
15 private static let gamePageURL = "http://www.dmm.com/netgame/social/-/gadgets/=/app_id=854854/"
16 private static let loginPageURLPrefix = "https://www.dmm.com/my/-/login/=/"
18 @IBOutlet private var webView: WebView!
20 override var nibName: NSNib.Name {
22 return .nibName(instanceOf: self)
25 private var flashTopLeft = NSPoint(x: 2600, y: 1445)
26 private var clipView: NSClipView {
28 return view as! NSClipView // swiftlint:disable:this force_cast
31 override func viewDidLoad() {
35 clipView.documentView = webView
39 webView.mainFrame.frameView.allowsScrolling = false
41 webView.applicationNameForUserAgent = AppDelegate.shared.appNameForUserAgent
42 webView.mainFrameURL = GameViewController.gamePageURL
47 webView.superview?.scroll(flashTopLeft)
50 @IBAction func reloadContent(_ sender: AnyObject?) {
52 guard let _ = webView.mainFrameURL else {
54 webView.mainFrameURL = GameViewController.gamePageURL
58 // ゲームページでない場合はゲームページを表示する
59 if webView.mainFrameURL != GameViewController.gamePageURL {
61 webView.mainFrameURL = GameViewController.gamePageURL
65 if webView.mainFrameURL.hasPrefix(GameViewController.loginPageURLPrefix) {
67 webView.reload(sender)
74 let prevDate = UserDefaults.standard[.prevReloadDate]
75 if Date(timeIntervalSinceNow: 0.0).timeIntervalSince(prevDate) < 1 * 60 {
77 let untilDate = prevDate.addingTimeInterval(1 * 60)
78 let date = DateFormatter.localizedString(from: untilDate, dateStyle: .none, timeStyle: .medium)
80 alert.messageText = LocalizedStrings.reloadTimeShortenMessage.string
81 let format = LocalizedStrings.reloadTimeShortenInfo.string
82 alert.informativeText = String(format: format, date)
88 webView.reload(sender)
90 UserDefaults.standard[.prevReloadDate] = Date(timeIntervalSinceNow: 0.0)
93 @IBAction func deleteCacheAndReload(_ sender: AnyObject?) {
95 let panel = ProgressPanel()
97 guard let window = view.window else { return }
98 guard let panelWindow = panel.window else { return }
101 panel.message = LocalizedStrings.deletingCacheInfo.string
104 window.beginSheet(panelWindow) { _ in NSSound(named: NSSound.Name("Submarine"))?.play() }
106 AppDelegate.shared.clearCache()
108 window.endSheet(panelWindow)
111 func screenshotOld() {
113 let frame = webView.visibleRect
114 let screenshotBorder = UserDefaults.standard[.screenShotBorderWidth]
115 let f = frame.insetBy(dx: -screenshotBorder, dy: -screenshotBorder)
117 guard let rep = webView.bitmapImageRepForCachingDisplay(in: f) else { return }
119 webView.cacheDisplay(in: frame, to: rep)
121 ScreenshotRegister(ApplicationDirecrories.screenshotSaveDirectoryURL)
122 .registerScreenshot(rep, name: localizedAppName())
125 @available(OSX 10.13, *)
128 let frame = view.visibleRect
129 let screenshotBorder = UserDefaults.standard[.screenShotBorderWidth]
130 let f = frame.insetBy(dx: -screenshotBorder, dy: -screenshotBorder)
131 let windowCoordinateFrame = view.convert(f, to: nil)
133 guard let window = view.window else { return Logger.shared.log("Can not get window") }
134 let screenCoordinsteFrame = window.convertToScreen(windowCoordinateFrame)
136 guard let screen = NSScreen.main else { return Logger.shared.log("Can not get Screen") }
137 let scFrame = screen.frame
139 guard let cxt = window.graphicsContext?.cgContext else { return Logger.shared.log("Cannot get Context") }
140 let deviceCoordinateFrame = cxt.convertToDeviceSpace(screenCoordinsteFrame)
141 let raio = deviceCoordinateFrame.size.width / screenCoordinsteFrame.size.width
143 let trimRect = CGRect(x: raio * screenCoordinsteFrame.origin.x,
144 y: raio * (scFrame.size.height - screenCoordinsteFrame.origin.y - screenCoordinsteFrame.size.height),
145 width: raio * screenCoordinsteFrame.size.width,
146 height: raio * screenCoordinsteFrame.size.height)
148 guard let fullSizeImage = CGDisplayCreateImage(CGMainDisplayID()) else { return Logger.shared.log("Can not get Image") }
150 guard let image = fullSizeImage.cropping(to: trimRect) else { return Logger.shared.log("Can not trim image") }
152 let rep = NSBitmapImageRep(cgImage: image)
154 if rep.size != NSSize(width: 800, height: 480) {
155 rep.size = NSSize(width: 800, height: 480)
158 ScreenshotRegister(ApplicationDirecrories.screenshotSaveDirectoryURL)
159 .registerScreenshot(rep, name: localizedAppName())
162 @IBAction func screenShot(_ sender: AnyObject?) {
164 if #available(OSX 10.13, *) {
174 override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
176 guard let action: Selector = menuItem.action else { return false }
180 case #selector(GameViewController.reloadContent(_:)):
181 guard let _ = webView.mainFrame else { return true }
182 guard let frameURL = webView.mainFrameURL else { return true }
185 case GameViewController.gamePageURL:
186 menuItem.title = LocalizedStrings.reload.string
188 case let s where s.hasPrefix(GameViewController.loginPageURLPrefix):
189 menuItem.title = LocalizedStrings.reload.string
192 menuItem.title = LocalizedStrings.backToGame.string
197 case #selector(GameViewController.deleteCacheAndReload(_:)):
200 case #selector(GameViewController.screenShot(_:)):
203 default: return false
208 extension GameViewController: WebFrameLoadDelegate, WebUIDelegate {
210 private static let excludeMenuItemTag = [
211 WebMenuItemTagOpenLinkInNewWindow,
212 WebMenuItemTagDownloadLinkToDisk,
213 WebMenuItemTagOpenImageInNewWindow,
214 WebMenuItemTagOpenFrameInNewWindow,
215 WebMenuItemTagGoBack,
216 WebMenuItemTagGoForward,
221 func webView(_ sender: WebView!, didFinishLoadFor frame: WebFrame!) {
223 guard let path = frame.dataSource?.initialRequest.url?.path else { return }
225 let handler: (JSContext?, JSValue?) -> Void = { (_, exception) in
227 if let exception = exception {
229 print("Caught exception in evaluteScript -> \(exception)")
233 print("Caught exception in evaluteScript")
237 if path.hasSuffix("gadgets/ifr") {
239 guard let context = frame.javaScriptContext else { return }
241 context.exceptionHandler = handler
242 context.evaluateScript(
243 ["var emb = document.getElementById('flashWrap');",
244 "var rect = emb.getBoundingClientRect();",
245 "var atop = rect.top;",
246 "var aleft = rect.left;"]
249 let top = context.objectForKeyedSubscript("atop").toDouble()
250 let left = context.objectForKeyedSubscript("aleft").toDouble()
251 flashTopLeft = NSPoint(x: CGFloat(left), y: webView.frame.size.height - CGFloat(top) - 480)
254 if path.hasSuffix("app_id=854854") {
256 guard let context = frame.javaScriptContext else { return }
258 context.exceptionHandler = handler
259 context.evaluateScript(
260 ["var iframe = document.getElementById('game_frame');",
261 "var validIframe = 0;",
264 " var rect = iframe.getBoundingClientRect();",
265 " var atop = rect.top;",
266 " var aleft = rect.left;",
270 let validIframe = context.objectForKeyedSubscript("validIframe").toInt32()
272 guard validIframe != 0 else { return }
274 let top = context.objectForKeyedSubscript("atop").toDouble()
275 let left = context.objectForKeyedSubscript("aleft").toDouble()
276 flashTopLeft = NSPoint(x: flashTopLeft.x + CGFloat(left), y: flashTopLeft.y - CGFloat(top))
282 func webView(_ sender: WebView!, contextMenuItemsForElement element: [AnyHashable: Any]!, defaultMenuItems: [Any]!) -> [Any]! {
284 guard let menuItems = defaultMenuItems as? [NSMenuItem] else { return [] }
286 return menuItems.filter { !GameViewController.excludeMenuItemTag.contains($0.tag) }