Re: [閒聊] 排程系統

看板mud_sanc (Sanctuary - 聖殿)作者 (揮淚斬馬雲)時間7年前 (2018/01/13 21:40), 7年前編輯推噓0(000)
留言0則, 0人參與, 最新討論串5/5 (看更多)
經思考後,crontab 還是廢棄好了。 目前決定還是回歸 set_times_check 的做法,然後以最近應該優先 完成的自動排程拍賣系統為例,/cmds/std/_blarket.c 裡面要加上 times_check 函數,以華麗與汙痕書店為例,它要透過下指令觸發, 使用者下指令,它才會去 set_times_check,所以我只要透過下指令 的方式設定排程即可,以書店為例,設定的呼叫段如下: 幾秒後 times_check->set_times_check(names,shop_files,({str,sk}),sk/50); 所以假設我希望 2/15 晚上 21:00 開啟拍賣,這時需要一個計算函 數,計算上面時間與現在時間的秒數差,這個有簡單的方式 Sat Jan 13 21:03:10 2018 現在時間 Thr Feb 15 21:00:00 2018 目標時間 年先不用管,上面做 sscanf 取出 mon 及 day: times=time(); sscanf(ctime(times),"%s %s %s %d:%d:%d %s",week,mon,day,hour,min,sec,year); tar_mon="Feb"; tar_day="15"; tar_hour=21; tar_min=0; t=0; // 這個迴圈做完只是一瞬間的事而已 while(mon!=tar_mon || day!=tar_day) { t+=86400; sscanf(ctime(times+t),"%s %s %s %d:%d:%d %s",week,mon,day, hour,min,sec,year); } 脫離上面 while 的條件就是 mon==tar_mon && day==tar_day,因為 不比年,所以迴圈最多跑三百多次。接著: t=t+(tar_hour-hour)*3600+(tar_min-min)*60; // 秒不用管 幾秒後 times_check->set_times_check("blarket","/cmds/std/_blarket",({參數}),t); 我剛有用 running 實驗,2849340 秒後就是 2018/2/15 晚上九點: if(1) { string week,mon,day,tar_mon,tar_day,year; int times,t,hour,min,sec,tar_hour,tar_min; // 以 2018/02/15 21:00 為例 times=time(); sscanf(ctime(times),"%s %s %s %d:%d:%d %s",week,mon,day,hour,min,sec,year); tar_mon="Feb"; tar_day="15"; tar_hour=21; tar_min=0; t=0; // 這個迴圈做完只是一瞬間的事而已 while(mon!=tar_mon || day!=tar_day) { t+=86400; sscanf(ctime(times+t),"%s %s %s %d:%d:%d %s",week,mon,day, hour,min,sec,year); } t=t+(tar_hour-hour)*3600+(tar_min-min)*60; write("t="+t+", ctime(times+t)="+ctime(times+t)+"\n"); } ========== 程式執行區 ========== t=2849340, ctime(times+t)=Thu Feb 15 21:00:58 2018 ========== 程式執行區 ========== 這比 crontab 穩定多了,因為不需要判斷年,就可以很簡單的做好 防止迴圈過大的判斷(例如在 while 迴圈內加上計數器,超過 400 次就代表給的時間有問題就不設定)。 而且,有需要時再設定即可。 就算是 loop 型的 times_check 同樣也可以交給目標物件去做,好 處就是自己的目標物件要跑怎麼樣的 loop 判斷,自己寫最彈性。 這裡還可以導入 boat 的概念: // 航行計劃 set("plane",({ ({"菲里德軍港","/u/l/laechan/area/felid/room/285-軍港",30,90}), ({"西斯迪克港","/u/l/laechan/area/sisdic/room/001",30,90}), ({"塔塔克高原",TR"015",30,90}),})); 仿照航行計劃,自己編拍賣計劃 // 拍賣計劃 set("blarket",([ "newyear":({ ({......,幾秒後,等待幾秒,..}), . . }), "santa": ... ])); 先編好拍賣計劃,再透過指令去設定,不同的節慶執行不同的拍賣 計劃即可,根據我 blarket 的寫法 void create() { seteuid(getuid(this_object())); if(file_exists("/open/cmds/blarket.o")) restore_object("/open/cmds/blarket"); else data["boards"]=([]); set("pre_clean",1); // 避免被系統當成真正的 room. 2010/08/28 } 我在這邊多寫一個讀取排程的物件資料即可。 以上應該是比較容易實行的方式,維持 times_check 的泛用性, wiz 不用習慣新的系統(crontab),只要知道 times_check 的原理 即可,而這東西已經存在很久也有範例了(/std/new_ob/boat.c)。 最近會優先改 blarket,改好後會實驗,接著就會改農場控制室, 將星星日改成可由系統去定時跑,例如六日一定會跑,再來可以一 三五跑一次之類的,這個改好後也會實驗,再有時間,就是月例大 賽的擲筊王比賽的定期每月月底或每月一號開啟,什麼時間開啟不 重要,因為開啟後至少 n 天的時間是線上玩家都可以去擲的。 Laechan -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.253.167.36 ※ 文章網址: https://www.ptt.cc/bbs/mud_sanc/M.1515850839.A.820.html ※ 編輯: laechan (111.253.167.36), 01/13/2018 21:46:05
文章代碼(AID): #1QMWnNWW (mud_sanc)
文章代碼(AID): #1QMWnNWW (mud_sanc)