# HG changeset patch # User sheepluva # Date 1447590923 -3600 # Node ID d3b603323b2b84de63817e335dcafeba27396e9d # Parent 437a60995fe1c82fc6dbe6d99547e7fd5ba3a1cf# Parent 43ad1122a3687e5834c44f2394a855319b7eeeb6 merge sdl2transition changes diff -r 43ad1122a368 -r d3b603323b2b CMakeLists.txt --- a/CMakeLists.txt Sun Nov 15 13:34:32 2015 +0100 +++ b/CMakeLists.txt Sun Nov 15 13:35:23 2015 +0100 @@ -8,6 +8,12 @@ endif() endforeach() +foreach(hwpolicy CMP0026) + if(POLICY ${hwpolicy}) + cmake_policy(SET ${hwpolicy} OLD) + endif() +endforeach() + set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules") include(${CMAKE_MODULE_PATH}/utils.cmake) diff -r 43ad1122a368 -r d3b603323b2b QTfrontend/util/LibavInteraction.cpp --- a/QTfrontend/util/LibavInteraction.cpp Sun Nov 15 13:34:32 2015 +0100 +++ b/QTfrontend/util/LibavInteraction.cpp Sun Nov 15 13:35:23 2015 +0100 @@ -33,8 +33,11 @@ #include "HWApplication.h" // compatibility section +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 8, 0) +#define av_codec_is_encoder(x) x->encode +#endif + #if LIBAVCODEC_VERSION_MAJOR < 55 -#define av_codec_is_encoder(x) x->encode #define AVCodecID CodecID #endif diff -r 43ad1122a368 -r d3b603323b2b README.md --- a/README.md Sun Nov 15 13:34:32 2015 +0100 +++ b/README.md Sun Nov 15 13:35:23 2015 +0100 @@ -1,6 +1,8 @@ Hedgewars - a turn based strategy game. ======================================= +[![Build Status](https://travis-ci.org/hedgewars/hw.svg)](https://travis-ci.org/hedgewars/hw) + Copyright 2004-2015 Andrey Korotaev and others. See QTfrontend/res/html/about.html and CREDITS for a complete list of authors. diff -r 43ad1122a368 -r d3b603323b2b gameServer/EngineInteraction.hs --- a/gameServer/EngineInteraction.hs Sun Nov 15 13:34:32 2015 +0100 +++ b/gameServer/EngineInteraction.hs Sun Nov 15 13:35:23 2015 +0100 @@ -196,6 +196,7 @@ , ("e$minesnum", 1) , ("e$minedudpct", 1) , ("e$explosives", 1) + , ("e$airmines", 1) , ("e$healthprob", 1) , ("e$hcaseamount", 1) , ("e$waterrise", 1) diff -r 43ad1122a368 -r d3b603323b2b gameServer/OfficialServer/Glicko2.hs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gameServer/OfficialServer/Glicko2.hs Sun Nov 15 13:35:23 2015 +0100 @@ -0,0 +1,70 @@ +{- + Glicko2, as described in http://www.glicko.net/glicko/glicko2.pdf +-} + +module OfficialServer.Glicko2 where + +data RatingData = RatingData { + ratingValue + , rD + , volatility :: Double + } +data GameData = GameData { + opponentRating :: RatingData, + gameScore :: Double + } + +τ, ε :: Double +τ = 0.3 +ε = 0.000001 + +g_φ :: Double -> Double +g_φ φ = 1 / sqrt (1 + 3 * φ^2 / pi^2) + +calcE :: RatingData -> GameData -> (Double, Double, Double) +calcE oldRating (GameData oppRating s) = ( + 1 / (1 + exp (g_φᵢ * (μᵢ - μ))) + , g_φᵢ + , s + ) + where + μ = (ratingValue oldRating - 1500) / 173.7178 + φ = rD oldRating / 173.7178 + μᵢ = (ratingValue oppRating - 1500) / 173.7178 + φᵢ = rD oppRating / 173.7178 + g_φᵢ = g_φ φᵢ + + +calcNewRating :: RatingData -> [GameData] -> RatingData +calcNewRating oldRating [] = RatingData (ratingValue oldRating) (173.7178 * sqrt (φ ^ 2 + σ ^ 2)) σ + where + φ = rD oldRating / 173.7178 + σ = volatility oldRating + +calcNewRating oldRating games = RatingData (173.7178 * μ' + 1500) (173.7178 * sqrt φ'sqr) σ' + where + _Es = map (calcE oldRating) games + υ = 1 / sum (map υ_p _Es) + υ_p (_Eᵢ, g_φᵢ, _) = g_φᵢ ^ 2 * _Eᵢ * (1 - _Eᵢ) + _Δ = υ * part1 + part1 = sum (map _Δ_p _Es) + _Δ_p (_Eᵢ, g_φᵢ, sᵢ) = g_φᵢ * (sᵢ - _Eᵢ) + + μ = (ratingValue oldRating - 1500) / 173.7178 + φ = rD oldRating / 173.7178 + σ = volatility oldRating + + a = log (σ ^ 2) + f :: Double -> Double + f x = exp x * (_Δ ^ 2 - φ ^ 2 - υ - exp x) / 2 / (φ ^ 2 + υ + exp x) ^ 2 - (x - a) / τ ^ 2 + + _A = a + _B = if _Δ ^ 2 > φ ^ 2 + υ then log (_Δ ^ 2 - φ ^ 2 - υ) else head . dropWhile ((>) 0 . f) . map (\k -> a - k * τ) $ [1 ..] + fA = f _A + fB = f _B + σ' = (\(_A, _, _, _) -> exp (_A / 2)) . head . dropWhile (\(_A, _, _B, _) -> abs (_B - _A) > ε) $ iterate step5 (_A, fA, _B, fB) + step5 (_A, fA, _B, fB) = let _C = _A + (_A - _B) * fA / (fB - fA); fC = f _C in + if fC * fB < 0 then (_B, fB, _C, fC) else (_A, fA / 2, _C, fC) + + φ'sqr = 1 / (1 / (φ ^ 2 + σ' ^ 2) + 1 / υ) + μ' = μ + φ'sqr * part1 diff -r 43ad1122a368 -r d3b603323b2b gameServer/OfficialServer/checker.hs --- a/gameServer/OfficialServer/checker.hs Sun Nov 15 13:34:32 2015 +0100 +++ b/gameServer/OfficialServer/checker.hs Sun Nov 15 13:35:23 2015 +0100 @@ -54,7 +54,7 @@ deriving Show serverAddress = "netserver.hedgewars.org" -protocolNumber = "49" +protocolNumber = "51" getLines :: Handle -> IO [B.ByteString] getLines h = g diff -r 43ad1122a368 -r d3b603323b2b gameServer/OfficialServer/updateRating.hs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gameServer/OfficialServer/updateRating.hs Sun Nov 15 13:35:23 2015 +0100 @@ -0,0 +1,104 @@ +{-# LANGUAGE ScopedTypeVariables, OverloadedStrings #-} +module Main where + +import Data.Maybe +import Data.TConfig +import qualified Data.ByteString.Char8 as B +import Database.MySQL.Simple +import Database.MySQL.Simple.QueryResults +import Database.MySQL.Simple.Result +import Control.Monad +import Control.Exception +import System.IO +import qualified Data.Map as Map +import Data.Time.Clock +------ +import OfficialServer.Glicko2 + + +queryEpochDates = "SELECT epoch, todatetime, todatetime + INTERVAL 1 week FROM rating_epochs WHERE epoch = (SELECT MAX(epoch) FROM rating_epochs)" +queryPreviousRatings = "SELECT v.userid, v.rating, v.rd, v.volatility FROM rating_values as v WHERE (v.epoch = (SELECT MAX(epoch) FROM rating_epochs))" +queryGameResults = + "SELECT \ + \ p.userid \ + \ , p.place \ + \ , COALESCE(vp.rating, 1500) \ + \ , COALESCE(vp.rd, 350) \ + \ , COALESCE(vp.volatility, 0.06) \ + \ , COALESCE(vo.rating, 1500) \ + \ , COALESCE(vo.rd, 350) \ + \ , COALESCE(vo.volatility, 0.06) \ + \ FROM \ + \ (SELECT epoch, todatetime FROM rating_epochs WHERE epoch = (SELECT MAX(epoch) FROM rating_epochs)) as e \ + \ JOIN rating_games as g ON (g.time BETWEEN e.todatetime AND e.todatetime + INTERVAL 1 WEEK - INTERVAL 1 SECOND) \ + \ JOIN rating_players as p ON (p.gameid = g.id) \ + \ JOIN rating_players as o ON (p.gameid = o.gameid AND p.userid <> o.userid AND (p.place = 0 OR (p.place <> o.place))) \ + \ LEFT OUTER JOIN rating_values as vp ON (vp.epoch = e.epoch AND vp.userid = p.userid) \ + \ LEFT OUTER JOIN rating_values as vo ON (vo.epoch = e.epoch AND vo.userid = o.userid) \ + \ GROUP BY p.userid, p.gameid, p.place \ + \ ORDER BY p.userid" +insertNewRatings = "INSERT INTO rating_values (userid, epoch, rating, rd, volatility) VALUES (?, ?, ?, ?, ?)" +insertNewEpoch = "INSERT INTO rating_epochs (epoch, todatetime) VALUES (?, ?)" + +mergeRatingData :: Map.Map Int (RatingData, [GameData]) -> [(Int, (RatingData, [GameData]))] -> Map.Map Int (RatingData, [GameData]) +mergeRatingData m s = foldr (unc0rry (Map.insertWith mf)) m s + where + mf (rd, gds) (_, gds2) = (rd, gds ++ gds2) + unc0rry f (a, b) c = f a b c + +calculateRatings dbConn = do + [(epochNum :: Int, fromDate :: UTCTime, toDate :: UTCTime)] <- query_ dbConn queryEpochDates + initRatingData <- (Map.fromList . map fromDBrating) `fmap` query_ dbConn queryPreviousRatings + gameData <- map fromGameResult `fmap` query_ dbConn queryGameResults + let mData = map getNewRating . Map.toList $ mergeRatingData initRatingData gameData + executeMany dbConn insertNewRatings $ map (toInsert epochNum) mData + execute dbConn insertNewEpoch (epochNum + 1, toDate) + return () + where + toInsert e (i, RatingData r rd v) = (i, e + 1, r, rd, v) + getNewRating (a, d) = (a, uncurry calcNewRating d) + convPlace :: Int -> Double + convPlace 0 = 0.5 + convPlace 1 = 1.0 + convPlace 2 = 0.0 + convPlace _ = error "Incorrect place value" + fromDBrating (a, b, c, d) = (a, (RatingData b c d, [])) + fromGameResult (pid, place, prating, pRD, pvol, orating, oRD, ovol) = + (pid, + (RatingData prating pRD pvol + , [GameData (RatingData orating oRD ovol) $ convPlace place])) + + +data DBConnectInfo = DBConnectInfo { + dbHost + , dbName + , dbLogin + , dbPassword :: B.ByteString + } + +cfgFileName :: String +cfgFileName = "hedgewars-server.ini" + + +readServerConfig :: ConnectInfo -> IO ConnectInfo +readServerConfig ci = do + cfg <- readConfig cfgFileName + return $ ci{ + connectHost = value "dbHost" cfg + , connectDatabase = value "dbName" cfg + , connectUser = value "dbLogin" cfg + , connectPassword = value "dbPassword" cfg + } + where + value n c = fromJust2 n $ getValue n c + fromJust2 n Nothing = error $ "Missing config entry " ++ n + fromJust2 _ (Just a) = a + +dbConnectionLoop mySQLConnectionInfo = + Control.Exception.handle (\(e :: SomeException) -> hPutStrLn stderr $ show e) $ + bracket + (connect mySQLConnectionInfo) + close + calculateRatings + +main = readServerConfig defaultConnectInfo >>= dbConnectionLoop diff -r 43ad1122a368 -r d3b603323b2b hedgewars/avwrapper/avwrapper.c --- a/hedgewars/avwrapper/avwrapper.c Sun Nov 15 13:34:32 2015 +0100 +++ b/hedgewars/avwrapper/avwrapper.c Sun Nov 15 13:35:23 2015 +0100 @@ -66,6 +66,17 @@ #if LIBAVCODEC_VERSION_MAJOR < 56 #define av_frame_alloc avcodec_alloc_frame #define av_frame_free av_freep +#define av_packet_rescale_ts rescale_ts + +static void rescale_ts(AVPacket *pkt, AVRational ctb, AVRational stb) +{ + if (pkt->pts != AV_NOPTS_VALUE) + pkt->pts = av_rescale_q(pkt->pts, ctb, stb); + if (pkt->dts != AV_NOPTS_VALUE) + pkt->dts = av_rescale_q(pkt->dts, ctb, stb); + if (pkt->duration > 0) + pkt->duration = av_rescale_q(pkt->duration, ctb, stb); +} #endif #if LIBAVCODEC_VERSION_MAJOR < 57 @@ -149,6 +160,10 @@ g_pAudio->sample_rate = g_Frequency; g_pAudio->channels = g_Channels; + // set time base as invers of sample rate + g_pAudio->time_base.den = g_pAStream->time_base.den = g_Frequency; + g_pAudio->time_base.num = g_pAStream->time_base.num = 1; + // set quality g_pAudio->bit_rate = 160000; @@ -192,6 +207,8 @@ AVPacket Packet; av_init_packet(&Packet); + Packet.data = NULL; + Packet.size = 0; int NumSamples = fread(g_pSamples, 2*g_Channels, g_NumSamples, g_pSoundFile); @@ -210,6 +227,8 @@ return FatalError("avcodec_encode_audio2 failed"); if (!got_packet) return 0; + + av_packet_rescale_ts(&Packet, g_pAudio->time_base, g_pAStream->time_base); #else if (NumSamples == 0) return 0; @@ -252,9 +271,9 @@ of which frame timestamps are represented. for fixed-fps content, timebase should be 1/framerate and timestamp increments should be identically 1. */ - g_pVideo->time_base.den = g_Framerate.num; - g_pVideo->time_base.num = g_Framerate.den; - //g_pVideo->gop_size = 12; /* emit one intra frame every twelve frames at most */ + g_pVideo->time_base.den = g_pVStream->time_base.den = g_Framerate.num; + g_pVideo->time_base.num = g_pVStream->time_base.num = g_Framerate.den; + g_pVideo->pix_fmt = AV_PIX_FMT_YUV420P; // set quality @@ -309,6 +328,9 @@ if (!g_pVFrame) return FatalError("Could not allocate frame"); + g_pVFrame->width = g_Width; + g_pVFrame->height = g_Height; + g_pVFrame->format = AV_PIX_FMT_YUV420P; g_pVFrame->linesize[0] = g_Width; g_pVFrame->linesize[1] = g_Width/2; g_pVFrame->linesize[2] = g_Width/2; @@ -343,6 +365,7 @@ Packet.size = 0; g_pVFrame->pts++; +#if LIBAVCODEC_VERSION_MAJOR < 58 if (g_pFormat->flags & AVFMT_RAWPICTURE) { /* raw video case. The API will change slightly in the near @@ -357,6 +380,7 @@ return 0; } else +#endif { #if LIBAVCODEC_VERSION_MAJOR >= 54 int got_packet; @@ -365,10 +389,7 @@ if (!got_packet) return 0; - if (Packet.pts != AV_NOPTS_VALUE) - Packet.pts = av_rescale_q(Packet.pts, g_pVideo->time_base, g_pVStream->time_base); - if (Packet.dts != AV_NOPTS_VALUE) - Packet.dts = av_rescale_q(Packet.dts, g_pVideo->time_base, g_pVStream->time_base); + av_packet_rescale_ts(&Packet, g_pVideo->time_base, g_pVStream->time_base); #else Packet.size = avcodec_encode_video(g_pVideo, g_OutBuffer, OUTBUFFER_SIZE, pFrame); if (Packet.size < 0) @@ -506,7 +527,7 @@ { do ret = WriteFrame(NULL); - while (ret >= 0); + while (ret > 0); if (ret < 0) return ret; } @@ -515,7 +536,7 @@ { ret = WriteAudioFrame(); } - while(ret >= 0); + while(ret > 0); if (ret < 0) return ret; diff -r 43ad1122a368 -r d3b603323b2b share/hedgewars/Data/Scripts/OfficialChallenges.lua --- a/share/hedgewars/Data/Scripts/OfficialChallenges.lua Sun Nov 15 13:34:32 2015 +0100 +++ b/share/hedgewars/Data/Scripts/OfficialChallenges.lua Sun Nov 15 13:35:23 2015 +0100 @@ -36,6 +36,8 @@ return("Racer Challenge #6") elseif LandDigest == "M256715557Scripts/Multiplayer/Racer.lua" then return("Racer Challenge #15") + elseif LandDigest == "M-1389184823Scripts/Multiplayer/Racer.lua" then + return("Racer Challenge #17") end end end