Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

partition battles by week

  • Loading branch information...
commit a354ebe43fd2da2aede4c49d0ee655e374841f38 1 parent 442c83a
Mattias Dalkvist authored April 09, 2013
17  src/bf3/bl.clj
@@ -8,7 +8,7 @@
8 8
   (:use [cheshire.core]
9 9
         [net.cgrand.enlive-html]
10 10
         [bf3.db]
11  
-        [bf3.info :only [parse-info]])
  11
+        [bf3.live :only [parse-info]])
12 12
   (:import [java.net URI DatagramPacket DatagramSocket InetAddress MulticastSocket]))
13 13
 
14 14
 (declare get-user get-live-info)
@@ -235,13 +235,14 @@
235 235
 (defn save-live-users
236 236
   ([] (save-live-users (time/now)))
237 237
   ([start]
238  
-     (when (> 60 (time/in-secs (time/interval start (time/now))))
239  
-       (doseq [[server id] server-ids]
240  
-         (let [info (get-users id)]
241  
-           (when (not-empty info) (save-bl-user! info))))
242  
-       (when (> 45 (time/in-secs (time/interval start (time/now))))
243  
-         (future (Thread/sleep 10000)
244  
-                 (save-live-users start))))))
  238
+     ;; (when (> 60 (time/in-secs (time/interval start (time/now))))
  239
+     ;;   (doseq [[server id] server-ids]
  240
+     ;;     (let [info (get-users id)]
  241
+     ;;       (when (not-empty info) (save-bl-user! info))))
  242
+     ;;   (when (> 45 (time/in-secs (time/interval start (time/now))))
  243
+     ;;     (future (Thread/sleep 10000)
  244
+     ;;             (save-live-users start))))
  245
+     ))
245 246
 
246 247
 (defn- get-platoon-info [id]
247 248
   (-> (client/get (str "http://battlelog.battlefield.com/bf3/platoon/" id "/listmembers/")
115  src/bf3/core.clj
@@ -5,7 +5,8 @@
5 5
         hiccup.core
6 6
         hiccup.page-helpers
7 7
         [bf3.db :only [get-ts-users get-bl-users get-battle]]
8  
-        [bf3.info :only[battle-info parse-info merge-infos]]
  8
+        [bf3.live :only [parse-info]]
  9
+        [bf3.info :only [battle-info merge-infos]]
9 10
         [cheshire.core :only [encode generate-string]])
10 11
   (:require (compojure [route :as route])
11 12
             (ring.util [response :as response])
@@ -382,7 +383,7 @@
382 383
 (defpage "/get-battle/:gameid" {:keys [gameid start end host] :or {start false end false
383 384
                                                                    host ((:headers (req/ring-request)) "host")}}
384 385
   (let [logs (bf3.db/get-battle  gameid :start start :end end)
385  
-        battle (->> logs  bf3.info/battle-info first)]
  386
+        battle (-> (bf3.info/battle-info :logs logs) first)]
386 387
     (battle-layout (when battle (list [:style {:type "text/css"} (gaka/css [:div.livecontainer :display "block"])]
387 388
                                       (into [:div.info]
388 389
                                             (conj (show-battle-info battle)
@@ -407,60 +408,61 @@
407 408
 
408 409
   (html5 (battles)))
409 410
 
410  
-(defpage "/gc/battles/" {:keys [testservers host server] :or {testservers false
411  
-                                                             server false
412  
-                                                             host ((:headers (req/ring-request)) "host")}}
  411
+(defpage "/gc/battles/:weeks" {:keys [testservers host server weeks] :or {testservers false
  412
+                                                                   server false
  413
+                                                                   host ((:headers (req/ring-request)) "host")
  414
+                                                                   weeks 0}}
413 415
   (battle-layout
414  
-          (javascript-tag (str "$(document).ready(function(){"
415  
-                               "$('a.toggle.users').click(function(){"
416  
-                               "$(this).closest('li').find('ul.users').toggle(); return false});"
417  
-                               "$('a.livescore').click(function(){"
418  
-                               "var onlink = $(this); var offlink = $(this).parent().find('a.toggle.score');"
419  
-                               " $.get($(this).attr('href'), function (response) {"
420  
-                               "$(onlink).closest('li').find('.livecontainer')"
421  
-                               ".replaceWith($('.livecontainer', response));"
422  
-                               "$(onlink).closest('li').find('.livecontainer').toggle('true');"
423  
-                               "$(onlink).toggle('false');$(offlink).toggle('true');"
424  
-                               "});"
425  
-                               "return false;});"
426  
-                               "$('a.toggle.score').click(function(){"
427  
-                               "$(this).toggle(); $(this).parent().find('a.livescore').toggle();"
428  
-                               "$(this).closest('li').find('.livecontainer').toggle('false');"
429  
-                               "return false;});"
430  
-                               "});"))
431  
-          (into [:div#battles]
432  
-                (for [btls (->> (battle-info) (partition-by :server))]
433  
-                  (into [:ul.battles]
434  
-                        (for [battle  btls]
435  
-                          (when (and (or (false? server) (= server (:server battle)))
436  
-                                     (or (true? testservers)
437  
-                                         (some #(= % (:server battle)) (vals bf3.bl/server-ids)))
438  
-                                     (< 15 (count (:live battle)))
439  
-                                     (< 1 (count (:users battle))))
440  
-                            [:li.battle
441  
-                             (into [:div.info]
442  
-                                   (concat ( show-battle-info battle)
443  
-                                           (list [:a {:class "livescore" :href
444  
-                                                      (str "http://" host
445  
-                                                           (if (or(= "work.dalkvist.se:8081" host)
446  
-                                                                  (= "localhost:8081" host)) "/get-battle/" "/battle/")
447  
-                                                           (:gameId battle) "?"
448  
-                                                           (encode-params {:start (-> battle :time :start)
449  
-                                                                           :end  (-> battle :time :end)}))}
450  
-                                                  "show score"]
451  
-                                                 [:a.toggle.score {:href ""} "hide score"])))
452  
-                             [:div.livecontainer]
453  
-                             (comment [:a.toggle.users {:href ""} "toggle users"]
454  
-                                      [:ul.users
455  
-                                       (for [user (->> (:users battle) (sort-by :clanTags)
456  
-                                                       (partition-by :clanTags)
457  
-                                                       (mapcat #(sort-by :personaName %)))]
458  
-                                         [:li.user [:span.name (str (when-not (empty? (:clanTags user))
459  
-                                                                      (str "[" (:clanTags user) "]"))
460  
-                                                                    (:personaName user))]
461  
-                                          [:span.expansions (bl/get-expansion-img (:expansions user) true)]])])
462  
-
463  
-                             ])))))))
  416
+   (javascript-tag (str "$(document).ready(function(){"
  417
+                        "$('a.toggle.users').click(function(){"
  418
+                        "$(this).closest('li').find('ul.users').toggle(); return false});"
  419
+                        "$('a.livescore').click(function(){"
  420
+                        "var onlink = $(this); var offlink = $(this).parent().find('a.toggle.score');"
  421
+                        " $.get($(this).attr('href'), function (response) {"
  422
+                        "$(onlink).closest('li').find('.livecontainer')"
  423
+                        ".replaceWith($('.livecontainer', response));"
  424
+                        "$(onlink).closest('li').find('.livecontainer').toggle('true');"
  425
+                        "$(onlink).toggle('false');$(offlink).toggle('true');"
  426
+                        "});"
  427
+                        "return false;});"
  428
+                        "$('a.toggle.score').click(function(){"
  429
+                        "$(this).toggle(); $(this).parent().find('a.livescore').toggle();"
  430
+                        "$(this).closest('li').find('.livecontainer').toggle('false');"
  431
+                        "return false;});"
  432
+                        "});"))
  433
+   (into [:div#battles]
  434
+         (for [btls (battle-info :weeks (try (Integer/parseInt weeks) (catch Exception ex 0)))]
  435
+           (into [:ul.battles]
  436
+                 (for [battle  btls]
  437
+                   (when (and (or (false? server) (= server (:server battle)))
  438
+                              (or (true? testservers)
  439
+                                  (some #(= % (:server battle)) (vals bf3.bl/server-ids)))
  440
+                              (< 15 (count (:live battle)))
  441
+                              (< 1 (count (:users battle))))
  442
+                     [:li.battle
  443
+                      (into [:div.info]
  444
+                            (concat ( show-battle-info battle)
  445
+                                    (list [:a {:class "livescore" :href
  446
+                                               (str "http://" host
  447
+                                                    (if (or(= "work.dalkvist.se:8081" host)
  448
+                                                           (= "localhost:8081" host)) "/get-battle/" "/battle/")
  449
+                                                    (:gameId battle) "?"
  450
+                                                    (encode-params {:start (-> battle :time :start)
  451
+                                                                    :end  (-> battle :time :end)}))}
  452
+                                           "show score"]
  453
+                                          [:a.toggle.score {:href ""} "hide score"])))
  454
+                      [:div.livecontainer]
  455
+                      (comment [:a.toggle.users {:href ""} "toggle users"]
  456
+                               [:ul.users
  457
+                                (for [user (->> (:users battle) (sort-by :clanTags)
  458
+                                                (partition-by :clanTags)
  459
+                                                (mapcat #(sort-by :personaName %)))]
  460
+                                  [:li.user [:span.name (str (when-not (empty? (:clanTags user))
  461
+                                                               (str "[" (:clanTags user) "]"))
  462
+                                                             (:personaName user))]
  463
+                                   [:span.expansions (bl/get-expansion-img (:expansions user) true)]])])
  464
+
  465
+                      ])))))))
464 466
 
465 467
 (defn- get-live [server]
466 468
   (let [id (str "live" server)
@@ -573,11 +575,10 @@
573 575
           (assoc-in resp [:headers "Cache-Control"] "public; max-age=10")
574 576
           resp)))))
575 577
 
576  
-(server/add-middleware cache-battles)
577  
-
578 578
 (defonce server (atom nil))
579 579
 
580 580
 (defn -main [& m]
  581
+  (server/add-middleware cache-battles)
581 582
   (let [port (Integer/parseInt (get (System/getenv) "PORT" "8081"))]
582 583
     (System/setProperty "java.net.preferIPv4Stack" "true")
583 584
     (reset! server (server/start port))))
17  src/bf3/db.clj
... ...
@@ -1,6 +1,7 @@
1 1
 (ns bf3.db
2 2
   (:use [somnium.congomongo]
3  
-        [somnium.congomongo.config :only [*mongo-config*]]))
  3
+        [somnium.congomongo.config :only [*mongo-config*]])
  4
+  (:require             [clj-time.core :as time]))
4 5
 
5 6
 (defn- split-mongo-url [url]
6 7
   "Parses mongodb url from heroku, eg. mongodb://user:pass@localhost:1234/db"
@@ -67,10 +68,18 @@
67 68
                                   {"users" {:$ne []}}
68 69
                                   {"gameId" gameid}]})))))
69 70
 
70  
-(defn get-battles-by-server [server-id]
71  
-  (do (maybe-init)
  71
+(defn get-battles-by-server [server-id & {:keys [start end weeks] :or {weeks 0}}]
  72
+  (let [t (time/today-at-midnight)
  73
+        start (if (nil? start) (time/minus t (time/weeks weeks)
  74
+                                                    (time/days (- (time/day-of-week t) 1)))
  75
+                  start)
  76
+        end (if (nil? end) (time/plus start (time/weeks 1))
  77
+                end)]
  78
+    (maybe-init)
72 79
       (map clean-users
73  
-           (fetch :bl-logs :where (hash-map :$and [ {:server server-id}])))))
  80
+           (fetch :bl-logs :where (hash-map :$and [ {:server server-id}
  81
+                                                    {"time" {:$gte (str start)
  82
+                                                             :$lte (str end)}}])))))
74 83
 
75 84
 (defn get-log [serverid gameid ]
76 85
   (fetch-one :bl-logs :sort {:time -1}
170  src/bf3/info.clj
@@ -4,7 +4,8 @@
4 4
             [clojure.core.memoize :as mem]
5 5
             [clj-time.core :as time]
6 6
             [clj-time.format :as time-format])
7  
-  (:use [bf3.db])
  7
+  (:use [bf3.db]
  8
+        [bf3.bl :only [server-ids]])
8 9
   (:import java.net.URL))
9 10
 
10 11
 
@@ -12,146 +13,6 @@
12 13
 (def ^{:dynamic true} *short-cache-time* (* 30 1000))
13 14
 (def ^{:dynamic true} *long-cache-time* (* 60 60 1000))
14 15
 
15  
-(defn- byte-to-char-val [bytes]
16  
-  (->> (if (coll? bytes) bytes [bytes])
17  
-       (map #(if (string? %) (Integer/parseInt %) %))
18  
-       (map (fn [n] (if (neg? n) (+ 256 n) n)))))
19  
-
20  
-(defn- parse-hex [strings]
21  
-  (->> strings (map #(if (string? %) (Integer/parseInt % 16) %)) byte-to-char-val (map char)  (reduce str)))
22  
-
23  
-(defn- charval? [n] (and (not= n 64) (> n 40)))
24  
-
25  
-(defn- parse-rawplayers
26  
-  ([players-team1 players-team2 players]
27  
-     (parse-rawplayers players-team1 players-team2 players []))
28  
-  ([players-team1 players-team2 players res]
29  
-     (if (empty? players)
30  
-       res
31  
-       (let [personaId (->> players  (take 4)
32  
-                            (map #(Integer/toHexString %))
33  
-                            (reduce str)
34  
-                            (#(Integer/parseInt % 16)))
35  
-
36  
-             postid  (->> players (drop 4))
37  
-             name (parse-hex (take  (first postid) (drop 1 postid)))
38  
-             postname  (drop (inc (first postid)) postid)
39  
-             taglength (first postname)
40  
-             clanTags (if (= 0 taglength) "" (str (parse-hex (take taglength (drop 1 postname)))))
41  
-             posttags (drop (inc taglength) postname)
42  
-             rank (first posttags)
43  
-             info (let [info (take 14 (drop 1 posttags))]
44  
-                     (merge (->> info
45  
-                                   (map #(Integer/toHexString %))
46  
-                                   (map #(if (and (not= "0" %) (= 1 (count %)))
47  
-                                           (str "0" %) %))
48  
-                                   (#(vector (take 4 %) (take 2 (drop 4 %)) (take 2 (drop 6 %))))
49  
-                                   (map #(reduce str %))
50  
-                                   (map #(Integer/parseInt % 16))
51  
-                                   (zipmap [:score :kills :deaths]))
52  
-                              {:squad (nth info 8)}))
53  
-             postinfo (drop 14 posttags)
54  
-             player (merge info {:team (if (> players-team1 (count res)) :1 :2)}
55  
-                           (zipmap [:personaName :clanTags :rank :personaId] [name clanTags rank personaId] ))]
56  
-         (recur players-team1 players-team2 postinfo (conj res player))))))
57  
-
58  
-(def parse-players (mem/memo-ttl parse-rawplayers *long-cache-time*))
59  
-
60  
-
61  
-(defn- get-live-stats [score users]
62  
-  (if (or (nil? users) (empty? users))
63  
-     score
64  
-    (->> (merge-with merge (->> users (partition-by :team)
65  
-                                (map (fn [t] (hash-map (:team (first t))
66  
-                                                      (->> t (map #(select-keys % [:kills :deaths]))
67  
-                                                           (apply merge-with +)))))
68  
-                                (reduce merge))
69  
-                     score)
70  
-         (#(if (= 2 (count (keys %)))
71  
-             (->> (merge-with merge % (apply hash-map (mapcat (fn [[t o]]
72  
-                                                                (vector
73  
-                                                                 (nth (keys %) t)
74  
-                                                                 (hash-map :revives
75  
-                                                                           ((fn [n] (if (neg? n) 0 n))
76  
-                                                                            (- (:kills (nth (vals %) o))
77  
-                                                                               (:deaths (nth (vals %) t )))))))
78  
-                                                              [[0 1] [1 0]])))
79  
-                  (map (fn [m] (hash-map (first m) (assoc (second m) :bleed ((fn [n] (if (neg? n) 0 n))
80  
-                                                                            (- (:max (second m))
81  
-                                                                               (:current (second m))
82  
-                                                                               (:deaths (second m))))))))
83  
-                  (apply merge))
84  
-             %)))))
85  
-
86  
-(def get-stats (mem/memo-ttl get-live-stats *long-cache-time*))
87  
-
88  
-
89  
-(defn parse-rawinfo [rawinfo]
90  
-  (try
91  
-    (let [info (->> rawinfo
92  
-                    (map #(Integer/parseInt (str %)))
93  
-                    byte-to-char-val
94  
-                    (map #(Integer/toHexString %))
95  
-                    (map #(if (and (not= "0" %) (= 1 (count %)))
96  
-                            (str "0" %) %)))
97  
-          gameId (->> info (drop 2)
98  
-                      (take 8)
99  
-                      (reduce str)
100  
-                      (#(Integer/parseInt % 16)))
101  
-          postid (->> info (drop 10))
102  
-          gameMode (->> postid (drop 1) (take (Integer/parseInt (first postid) 16))
103  
-                        (map #(char (Integer/parseInt % 16))) (reduce str))
104  
-          postmode (->> postid  (drop (inc (Integer/parseInt (first postid) 16))))
105  
-          mapvariant (first postmode)
106  
-          score (try (let [l (Integer/parseInt (first (drop 1 postmode)) 16)
107  
-                           infos (->> postmode (drop 2) (take l))]
108  
-                       {:score (if (re-find #"squaddeath" (s/lower-case gameMode))
109  
-                                 (->> infos (partition-all 5)
110  
-                                      (map (fn [t] (vector (keyword (str (Integer/parseInt (first t))))
111  
-                                                          (->> (rest t) (partition-all 2)
112  
-                                                               (map #(reduce str %))
113  
-                                                               (map #(Integer/parseInt % 16))
114  
-                                                               (zipmap [:current :max])))))
115  
-                                      flatten (apply hash-map))
116  
-                                 (->> infos
117  
-                                      (#(if (re-find #"rush" (s/lower-case gameMode))
118  
-                                          (vector (take 2 (drop 2 %)) (take 2 (drop 4 %))
119  
-                                                  (take 1 (drop (+ 2 (/ l 2)) %))
120  
-                                                  (take 1 (drop (+ 3 (/ l 2)) %)))
121  
-                                          (vector (take 2 (drop 1 %)) (take 2 (drop 3 %))
122  
-                                                  (take 2 (drop (+ 1 (/ l 2)) %))
123  
-                                                  (take 2 (drop (+ 3 (/ l 2)) %)))))
124  
-                                      (map #(reduce str %))
125  
-                                      (map #(if (empty? %) 0 (Integer/parseInt % 16)))
126  
-                                      (partition-all 2)
127  
-                                      (map #(zipmap [:current :max ] %))
128  
-                                      (zipmap [:1 :2])))})
129  
-                     (catch Exception e
130  
-                       (println "score error" e)))
131  
-          postinfo (->> postmode  (drop (+ 2 (Integer/parseInt (first (drop 1 postmode)) 16))))
132  
-          currentMap (->> postinfo
133  
-                          (drop 1) (take (Integer/parseInt (first postinfo) 16))
134  
-                          parse-hex
135  
-                          (reduce str))
136  
-          postmap (->> postinfo (drop (inc (Integer/parseInt (first postinfo) 16))))
137  
-          maxplayers (Integer/parseInt  (first postmap) 16)
138  
-          players-team1 (if-let [n (first (drop 4 postmap))]
139  
-                          (Integer/parseInt n  16) 0)
140  
-          players-team2 (if-let [n (first (drop 5 postmap))]
141  
-                          (Integer/parseInt n  16) 0)
142  
-          playerstart (drop 12 postmap)
143  
-          players (try (->> playerstart
144  
-                            (map #(Integer/parseInt % 16))
145  
-                            (parse-players players-team1 players-team2))
146  
-                       (catch Exception  e))
147  
-          stats (try (get-stats (:score score) players)
148  
-                     (catch Exception e))]
149  
-      (zipmap [:gameId :gameMode :currentMap :maxplayers :users  :mapVariant :stats]
150  
-              [gameId gameMode currentMap maxplayers players mapvariant stats]))
151  
-    (catch Exception e)))
152  
-
153  
-(def parse-info (mem/memo-ttl parse-rawinfo *long-cache-time*))
154  
-
155 16
 (defn merge-live-infos [infos]
156 17
   (reduce (fn [l1 l2]
157 18
             (let [m (merge l1 l2)
@@ -187,15 +48,14 @@
187 48
 (defn- parse-battle-infos
188 49
   ([logs]
189 50
      (->> logs
190  
-          (sort-by :server)
191  
-          (filter (fn [b] (some (fn [[team score]] (not= 0 (:max score))) (:stats b))))
192  
-          (partition-by :server)
193  
-          (map #(sort-by :time (fn [t1 t2] (time/after? (time-format/parse t1) (time-format/parse t2))) %))
194  
-          (mapcat #(partition-by
195  
-                    (fn [b] (str (:gameId b) (:currentMap b) (:gameMode b) (:mapVariant b)
196  
-                                (:vehicles b) (:mapMode b)
197  
-                                  (some (fn [[t s]] (apply = (vals (select-keys s [:max :current]))))
198  
-                                        (:stats b)))) %))
  51
+          (filter (fn [b] (and (not-empty (:users b)))
  52
+                    (some (fn [[team score]] (not= 0 (:max score))) (:stats b))))
  53
+
  54
+          (#(partition-by
  55
+             (fn [b] (str (:gameId b) (:currentMap b) (:gameMode b) (:mapVariant b)
  56
+                         (:vehicles b) (:mapMode b)
  57
+                         (some (fn [[t s]] (apply = (vals (select-keys s [:max :current]))))
  58
+                               (:stats b)))) %))
199 59
           (filter #(< 15 (count %))))))
200 60
 
201 61
 (comment
@@ -207,9 +67,15 @@
207 67
                    (= 1 (:current score)))))
208 68
         (:stats b)))
209 69
 
210  
-(defn- get-battle-infos
211  
-  ([] (get-battle-infos (get-bl-users)))
  70
+(defn- get-battles
212 71
   ([logs]
213 72
      (pmap get-battle-info (parse-battle-infos logs))))
214 73
 
  74
+(defn- get-battle-infos
  75
+  ([& {:keys [weeks logs] :or {weeks 0}}]
  76
+     (if logs (get-battles logs)
  77
+       (pmap (fn [id] (filter #(not-empty (:live %))
  78
+                             (get-battles (get-battles-by-server id :weeks weeks))))
  79
+             (vals server-ids)))))
  80
+
215 81
 (def battle-info (mem/memo-ttl get-battle-infos *short-cache-time*))
152  src/bf3/live.clj
... ...
@@ -0,0 +1,152 @@
  1
+(ns bf3.live
  2
+  (:require [clojure.string :as s]
  3
+            [clojure.core.cache :as cache]
  4
+            [clojure.core.memoize :as mem]
  5
+            [clj-time.core :as time]
  6
+            [clj-time.format :as time-format])
  7
+  (:use [bf3.db])
  8
+  (:import java.net.URL))
  9
+
  10
+(def ^{:dynamic true} *cache-time* (* 2 60 1000))
  11
+(def ^{:dynamic true} *short-cache-time* (* 30 1000))
  12
+(def ^{:dynamic true} *long-cache-time* (* 60 60 1000))
  13
+
  14
+(defn- byte-to-char-val [bytes]
  15
+  (->> (if (coll? bytes) bytes [bytes])
  16
+       (map #(if (string? %) (Integer/parseInt %) %))
  17
+       (map (fn [n] (if (neg? n) (+ 256 n) n)))))
  18
+
  19
+(defn- parse-hex [strings]
  20
+  (->> strings (map #(if (string? %) (Integer/parseInt % 16) %)) byte-to-char-val (map char)  (reduce str)))
  21
+
  22
+(defn- charval? [n] (and (not= n 64) (> n 40)))
  23
+
  24
+(defn- parse-rawplayers
  25
+  ([players-team1 players-team2 players]
  26
+     (parse-rawplayers players-team1 players-team2 players []))
  27
+  ([players-team1 players-team2 players res]
  28
+     (if (empty? players)
  29
+       res
  30
+       (let [personaId (->> players  (take 4)
  31
+                            (map #(Integer/toHexString %))
  32
+                            (reduce str)
  33
+                            (#(Integer/parseInt % 16)))
  34
+
  35
+             postid  (->> players (drop 4))
  36
+             name (parse-hex (take  (first postid) (drop 1 postid)))
  37
+             postname  (drop (inc (first postid)) postid)
  38
+             taglength (first postname)
  39
+             clanTags (if (= 0 taglength) "" (str (parse-hex (take taglength (drop 1 postname)))))
  40
+             posttags (drop (inc taglength) postname)
  41
+             rank (first posttags)
  42
+             info (let [info (take 14 (drop 1 posttags))]
  43
+                     (merge (->> info
  44
+                                   (map #(Integer/toHexString %))
  45
+                                   (map #(if (and (not= "0" %) (= 1 (count %)))
  46
+                                           (str "0" %) %))
  47
+                                   (#(vector (take 4 %) (take 2 (drop 4 %)) (take 2 (drop 6 %))))
  48
+                                   (map #(reduce str %))
  49
+                                   (map #(Integer/parseInt % 16))
  50
+                                   (zipmap [:score :kills :deaths]))
  51
+                              {:squad (nth info 8)}))
  52
+             postinfo (drop 14 posttags)
  53
+             player (merge info {:team (if (> players-team1 (count res)) :1 :2)}
  54
+                           (zipmap [:personaName :clanTags :rank :personaId] [name clanTags rank personaId] ))]
  55
+         (recur players-team1 players-team2 postinfo (conj res player))))))
  56
+
  57
+(def parse-players (mem/memo-ttl parse-rawplayers *long-cache-time*))
  58
+
  59
+
  60
+(defn- get-live-stats [score users]
  61
+  (if (or (nil? users) (empty? users))
  62
+     score
  63
+    (->> (merge-with merge (->> users (partition-by :team)
  64
+                                (map (fn [t] (hash-map (:team (first t))
  65
+                                                      (->> t (map #(select-keys % [:kills :deaths]))
  66
+                                                           (apply merge-with +)))))
  67
+                                (reduce merge))
  68
+                     score)
  69
+         (#(if (= 2 (count (keys %)))
  70
+             (->> (merge-with merge % (apply hash-map (mapcat (fn [[t o]]
  71
+                                                                (vector
  72
+                                                                 (nth (keys %) t)
  73
+                                                                 (hash-map :revives
  74
+                                                                           ((fn [n] (if (neg? n) 0 n))
  75
+                                                                            (- (:kills (nth (vals %) o))
  76
+                                                                               (:deaths (nth (vals %) t )))))))
  77
+                                                              [[0 1] [1 0]])))
  78
+                  (map (fn [m] (hash-map (first m) (assoc (second m) :bleed ((fn [n] (if (neg? n) 0 n))
  79
+                                                                            (- (:max (second m))
  80
+                                                                               (:current (second m))
  81
+                                                                               (:deaths (second m))))))))
  82
+                  (apply merge))
  83
+             %)))))
  84
+
  85
+(def get-stats (mem/memo-ttl get-live-stats *long-cache-time*))
  86
+
  87
+
  88
+(defn parse-rawinfo [rawinfo]
  89
+  (try
  90
+    (let [info (->> rawinfo
  91
+                    (map #(Integer/parseInt (str %)))
  92
+                    byte-to-char-val
  93
+                    (map #(Integer/toHexString %))
  94
+                    (map #(if (and (not= "0" %) (= 1 (count %)))
  95
+                            (str "0" %) %)))
  96
+          gameId (->> info (drop 2)
  97
+                      (take 8)
  98
+                      (reduce str)
  99
+                      (#(Integer/parseInt % 16)))
  100
+          postid (->> info (drop 10))
  101
+          gameMode (->> postid (drop 1) (take (Integer/parseInt (first postid) 16))
  102
+                        (map #(char (Integer/parseInt % 16))) (reduce str))
  103
+          postmode (->> postid  (drop (inc (Integer/parseInt (first postid) 16))))
  104
+          mapvariant (first postmode)
  105
+          score (try (let [l (Integer/parseInt (first (drop 1 postmode)) 16)
  106
+                           infos (->> postmode (drop 2) (take l))]
  107
+                       {:score (if (re-find #"squaddeath" (s/lower-case gameMode))
  108
+                                 (->> infos (partition-all 5)
  109
+                                      (map (fn [t] (vector (keyword (str (Integer/parseInt (first t))))
  110
+                                                          (->> (rest t) (partition-all 2)
  111
+                                                               (map #(reduce str %))
  112
+                                                               (map #(Integer/parseInt % 16))
  113
+                                                               (zipmap [:current :max])))))
  114
+                                      flatten (apply hash-map))
  115
+                                 (->> infos
  116
+                                      (#(if (re-find #"rush" (s/lower-case gameMode))
  117
+                                          (vector (take 2 (drop 2 %)) (take 2 (drop 4 %))
  118
+                                                  (take 1 (drop (+ 2 (/ l 2)) %))
  119
+                                                  (take 1 (drop (+ 3 (/ l 2)) %)))
  120
+                                          (vector (take 2 (drop 1 %)) (take 2 (drop 3 %))
  121
+                                                  (take 2 (drop (+ 1 (/ l 2)) %))
  122
+                                                  (take 2 (drop (+ 3 (/ l 2)) %)))))
  123
+                                      (map #(reduce str %))
  124
+                                      (map #(if (empty? %) 0 (Integer/parseInt % 16)))
  125
+                                      (partition-all 2)
  126
+                                      (map #(zipmap [:current :max ] %))
  127
+                                      (zipmap [:1 :2])))})
  128
+                     (catch Exception e
  129
+                       (println "score error" e)))
  130
+          postinfo (->> postmode  (drop (+ 2 (Integer/parseInt (first (drop 1 postmode)) 16))))
  131
+          currentMap (->> postinfo
  132
+                          (drop 1) (take (Integer/parseInt (first postinfo) 16))
  133
+                          parse-hex
  134
+                          (reduce str))
  135
+          postmap (->> postinfo (drop (inc (Integer/parseInt (first postinfo) 16))))
  136
+          maxplayers (Integer/parseInt  (first postmap) 16)
  137
+          players-team1 (if-let [n (first (drop 4 postmap))]
  138
+                          (Integer/parseInt n  16) 0)
  139
+          players-team2 (if-let [n (first (drop 5 postmap))]
  140
+                          (Integer/parseInt n  16) 0)
  141
+          playerstart (drop 12 postmap)
  142
+          players (try (->> playerstart
  143
+                            (map #(Integer/parseInt % 16))
  144
+                            (parse-players players-team1 players-team2))
  145
+                       (catch Exception  e))
  146
+          stats (try (get-stats (:score score) players)
  147
+                     (catch Exception e))]
  148
+      (zipmap [:gameId :gameMode :currentMap :maxplayers :users  :mapVariant :stats]
  149
+              [gameId gameMode currentMap maxplayers players mapvariant stats]))
  150
+    (catch Exception e)))
  151
+
  152
+(def parse-info (mem/memo-ttl parse-rawinfo *long-cache-time*))

0 notes on commit a354ebe

Please sign in to comment.
Something went wrong with that request. Please try again.