Check-in [ecc28d369e]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fleet status indication
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ecc28d369eeafceb39b91fbd049b9e86d47abfba
User & Date: linna 2016-10-30 08:03:29
Context
2016-10-30
08:03
Fleet status indication check-in: ba0b329442 user: linna tags: trunk
08:03
Fleet status indication check-in: ecc28d369e user: linna tags: trunk
2016-10-29
09:37
build shipType 3 check-in: 17134dfdfb user: linna tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to WarshipGirlsRSniffer/Protocol/Response/Index/GetInitConfigs.cs.

32
33
34
35
36
37
38
39


40

        [JsonIgnore] public DefaultTable<ShipCard> ShipCard => _shipCard ?? (_shipCard = shipCard.ToDefaultTable(x => x.cid));

        [JsonIgnore] private DefaultTable<ShipEquipment> _shipEquipments;
        [JsonIgnore] public DefaultTable<ShipEquipment> ShipEquipment => _shipEquipments ?? (_shipEquipments = shipEquipmnt.ToDefaultTable(x => x.cid));

        [JsonIgnore] private DefaultTable<ShipCampaignLevel> _shipCampaignLevel;
        [JsonIgnore] public DefaultTable<ShipCampaignLevel> ShipCampaignLevel => _shipCampaignLevel ?? (_shipCampaignLevel = shipCampaignLevel.ToDefaultTable(x => x.id));
    }


}








|
>
>
|
>
32
33
34
35
36
37
38
39
40
41
42
43
        [JsonIgnore] public DefaultTable<ShipCard> ShipCard => _shipCard ?? (_shipCard = shipCard.ToDefaultTable(x => x.cid));

        [JsonIgnore] private DefaultTable<ShipEquipment> _shipEquipments;
        [JsonIgnore] public DefaultTable<ShipEquipment> ShipEquipment => _shipEquipments ?? (_shipEquipments = shipEquipmnt.ToDefaultTable(x => x.cid));

        [JsonIgnore] private DefaultTable<ShipCampaignLevel> _shipCampaignLevel;
        [JsonIgnore] public DefaultTable<ShipCampaignLevel> ShipCampaignLevel => _shipCampaignLevel ?? (_shipCampaignLevel = shipCampaignLevel.ToDefaultTable(x => x.id));

        [JsonIgnore] private DefaultTable<PveExplore> _pveExplore;
        [JsonIgnore] public DefaultTable<PveExplore> PveExplore => _pveExplore ?? (_pveExplore = pveExplore.ToDefaultTable(x => x.id));
    }
}

Changes to WarshipGirlsRSniffer/View/Controls/ShipStatus.xaml.

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
                        <Setter Property="Text" Value="正常" />
                        <Setter Property="Background" Value="LightGreen" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Status}" Value="Repair">
                        <Setter Property="Text" Value="修理中" />
                        <Setter Property="Background" Value="LightBlue" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Fleet.Status}" Value="Explore">
                        <Setter Property="Text" Value="远征中" />
                        <Setter Property="Background" Value="Yellow" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Status}" Value="HeavilyDamaged">
                        <Setter Property="Text" Value="大破" />
                        <Setter Property="Background" Value="Red" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</UserControl>







|












17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
                        <Setter Property="Text" Value="正常" />
                        <Setter Property="Background" Value="LightGreen" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Status}" Value="Repair">
                        <Setter Property="Text" Value="修理中" />
                        <Setter Property="Background" Value="LightBlue" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Fleet.FleetStatus}" Value="Explore">
                        <Setter Property="Text" Value="远征中" />
                        <Setter Property="Background" Value="Yellow" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Status}" Value="HeavilyDamaged">
                        <Setter Property="Text" Value="大破" />
                        <Setter Property="Background" Value="Red" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</UserControl>

Changes to WarshipGirlsRSniffer/View/Converter/BuildShipTypeToDescriptionConverter.cs.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
            }

            switch((Vo.BuildShipType)value) {
                case Vo.BuildShipType.Unknown: return null;
                case Vo.BuildShipType.Cruiser: return "巡洋舰";
                case Vo.BuildShipType.Destroyer: return "驱逐舰";
                case Vo.BuildShipType.Carrier: return "航空母舰";
                default:return (byte)(Vo.BuildShipType)value + "类";
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}







|









13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
            }

            switch((Vo.BuildShipType)value) {
                case Vo.BuildShipType.Unknown: return null;
                case Vo.BuildShipType.Cruiser: return "巡洋舰";
                case Vo.BuildShipType.Destroyer: return "驱逐舰";
                case Vo.BuildShipType.Carrier: return "航空母舰";
                default:return $"#{(byte)(Vo.BuildShipType)value}";
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

Changes to WarshipGirlsRSniffer/View/Docks.xaml.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>

                    <TextBlock Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Text="{Binding Id}" VerticalAlignment="Center" Margin="10,0" FontSize="16" />
                    <TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding Title}" Margin="0,4" FontSize="14" />
                    <TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding RemainingTime, StringFormat={}{0:hh':'mm':'ss}}" Margin="0,4" />
                </Grid>
                <Border.Style>
                    <Style TargetType="Border">
                        <Setter Property="Visibility" Value="Visible" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Locked}" Value="True">
                                <Setter Property="Visibility" Value="Collapsed" />







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>

                    <TextBlock Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Text="{Binding Id}" VerticalAlignment="Center" Margin="10,0" FontSize="16" />
                    <TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding Title}" Margin="0,4" FontSize="14" />
                    <TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding RemainingTime, StringFormat={}{0:hh\\:mm\\:ss}}" Margin="0,4" />
                </Grid>
                <Border.Style>
                    <Style TargetType="Border">
                        <Setter Property="Visibility" Value="Visible" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Locked}" Value="True">
                                <Setter Property="Visibility" Value="Collapsed" />

Changes to WarshipGirlsRSniffer/View/Fleets.xaml.

1
2
3
4
5
6
7
8
9
10
11
12




































13
14
15
16
17
18
19
20
















21
22
23
24



































25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<UserControl x:Class="WarshipGirlsRSniffer.View.Fleets"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WarshipGirlsRSniffer.View"
             xmlns:control="clr-namespace:WarshipGirlsRSniffer.Controls"
             xmlns:vm="clr-namespace:WarshipGirlsRSniffer.Vm"
             xmlns:vc="clr-namespace:WarshipGirlsRSniffer.View.Controls"
             mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel>
        <ListBox ItemsSource="{Binding}" Background="{x:Null}" BorderThickness="0" Margin="5,5,5,1" x:Name="selector">




































            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate DataType="vm:FleetVm">
                    <TextBlock Text="{Binding Title}" />
















                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>




































        <ItemsControl Margin="5,1,5,5" ItemsSource="{Binding SelectedItem.Ships, ElementName=selector}"
                      BorderThickness="1,1,0,0" BorderBrush="{DynamicResource {x:Static SystemColors.ScrollBarBrushKey}}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Columns="2" Grid.IsSharedSizeScope="True" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="vm:ShipVm">
                    <Border BorderThickness="0,0,1,1" BorderBrush="{DynamicResource {x:Static SystemColors.ScrollBarBrushKey}}">
                        <Grid Margin="5">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" MinWidth="72" SharedSizeGroup="ShipInfo" />
                                <ColumnDefinition Width="Auto" MinWidth="72" SharedSizeGroup="ShipLevel" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />











|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<UserControl x:Class="WarshipGirlsRSniffer.View.Fleets"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WarshipGirlsRSniffer.View"
             xmlns:control="clr-namespace:WarshipGirlsRSniffer.Controls"
             xmlns:vm="clr-namespace:WarshipGirlsRSniffer.Vm"
             xmlns:vc="clr-namespace:WarshipGirlsRSniffer.View.Controls"
             mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel>
        <ListBox ItemsSource="{Binding}" Background="{x:Null}" BorderThickness="0" Margin="3" x:Name="selector">
            <ListBox.Style>
                <Style TargetType="ListBox">
                    <Style.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="SelectedItem"
                                           Value="{x:Null}" />
                                <Condition Property="HasItems"
                                           Value="True" />
                            </MultiTrigger.Conditions>
                            <Setter Property="SelectedIndex"
                                    Value="0" />
                        </MultiTrigger>
                    </Style.Triggers>
                </Style>
            </ListBox.Style>
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="SnapsToDevicePixels" Value="true"/>
                    <Setter Property="OverridesDefaultStyle" Value="true"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ListBoxItem">
                                <Border Name="Bd" Padding="4,2" SnapsToDevicePixels="True" BorderThickness="0,0,0,2">
                                    <ContentPresenter />
                                </Border>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsSelected" Value="True">
                                        <Setter TargetName="Bd" Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListBox.ItemContainerStyle>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate DataType="vm:FleetVm">
                    <TextBlock Text="{Binding Title}" Padding="4,2">
                        <TextBlock.Style>
                            <Style TargetType="TextBlock">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding Status}" Value="Repair">
                                        <Setter Property="Background" Value="LightBlue" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding Status}" Value="Explore">
                                        <Setter Property="Background" Value="Yellow" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding Status}" Value="HeavilyDamaged">
                                        <Setter Property="Background" Value="Red" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBlock.Style>
                    </TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <TextBlock Padding="10,2" Margin="3,0" DataContext="{Binding SelectedItem, ElementName=selector}">
            <TextBlock.Style>
                <Style TargetType="TextBlock">
                    <Setter Property="Text" Value="没有数据" />
                    <Setter Property="Background" Value="LightGray" />

                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Status}" Value="Normal">
                            <Setter Property="Text" Value="正常" />
                            <Setter Property="Background" Value="LightGreen" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Status}" Value="Repair">
                            <Setter Property="Background" Value="LightBlue" />
                            <Setter Property="Text" Value="{Binding SlowestRepair.RemainingTime, StringFormat='修理中 - {0:hh\\:mm\\:ss}'}" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Status}" Value="Explore">
                            <Setter Property="Background" Value="Yellow" />
                            <Setter Property="Text">
                                <Setter.Value>
                                    <MultiBinding StringFormat="远征中 - {0} - {1:hh\:mm\:ss}">
                                        <Binding Path="Explore.Title" />
                                        <Binding Path="Explore.RemainingTime" />
                                    </MultiBinding>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Status}" Value="HeavilyDamaged">
                            <Setter Property="Text" Value="大破" />
                            <Setter Property="Background" Value="Red" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
        </TextBlock>

        <ItemsControl Margin="3" ItemsSource="{Binding SelectedItem.Ships, ElementName=selector}"
                      BorderThickness="1,1,0,0" BorderBrush="{DynamicResource {x:Static SystemColors.ScrollBarBrushKey}}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Columns="2" Grid.IsSharedSizeScope="True" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="vm:ShipVm">
                    <Border BorderThickness="0,0,1,1" BorderBrush="{DynamicResource {x:Static SystemColors.ScrollBarBrushKey}}">
                        <Grid Margin="3">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" MinWidth="72" SharedSizeGroup="ShipInfo" />
                                <ColumnDefinition Width="Auto" MinWidth="72" SharedSizeGroup="ShipLevel" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />

Changes to WarshipGirlsRSniffer/View/Fleets.xaml.cs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14




15


using System.Windows.Controls;

namespace WarshipGirlsRSniffer.View
{
    /// <summary>
    /// Fleets.xaml 的交互逻辑
    /// </summary>
    public partial class Fleets : UserControl
    {
        public Fleets()
        {
            InitializeComponent();
        }
    }




}















|
>
>
>
>
|
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System.Windows.Controls;

namespace WarshipGirlsRSniffer.View
{
    /// <summary>
    /// Fleets.xaml 的交互逻辑
    /// </summary>
    public partial class Fleets : UserControl
    {
        public Fleets()
        {
            InitializeComponent();
        }

        private void selector_TargetUpdated(object sender, System.Windows.Data.DataTransferEventArgs e)
        {
            ListBox lb = sender as ListBox;
            if(lb?.HasItems == true) lb.SelectedIndex = 0;
        }
    }
}

Changes to WarshipGirlsRSniffer/Vm/BuildDockVm.cs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
using Linnaea.Extensions;
using System;
using System.Threading;
using WarshipGirlsRSniffer.Vo;

namespace WarshipGirlsRSniffer.Vm
{
    public class BuildDockVm : VmBase<BuildDockVm>
    {
        private static readonly View.Converter.BuildShipTypeToDescriptionConverter cvt = new View.Converter.BuildShipTypeToDescriptionConverter();

        private BuildDock vo;
        private readonly VmDock dock;
        private readonly Timer timer;

        public BuildDock Vo {
            get { return vo; }







            set { vo = value; RaiseMultiPropertyChanged(); UpdateTimer(this); }
        }

        private DateTimeOffset? _endTime;
        public DateTimeOffset? EndTime => _endTime;
        public byte Id => vo.id;
        public bool Locked => vo.locked != 0;
        public BuildShipType ShipType => (BuildShipType)vo.shipType;
        public string Title => cvt.Convert(ShipType, typeof(string), null, null) as string;
        public TimeSpan? RemainingTime {
            get
            {
                if(_endTime == null) {
                    return null;
                }
                var delta = _endTime.Value - DateTimeOffset.Now;
                return delta.Ticks < 0 ? TimeSpan.Zero : delta;
            }
        }

        public BuildDockVm(BuildDock vo, VmDock dock)
        {
            this.vo = vo;
            this.dock = dock;

            timer = new Timer(UpdateTimer, null, -1, -1);
            UpdateTimer(this);
        }

        private void UpdateTimer(object _)
        {
            RaisePropertyChanged(nameof(RemainingTime));
            if(_ != null) {
                _endTime = vo.endTime == 0 ? (DateTimeOffset?)null : DateTimeOffsetEx.FromUnixTimeSeconds(vo.endTime);
                if(RemainingTime.HasValue && RemainingTime != TimeSpan.Zero) {
                    timer.Change(1000, 1000);
                }
            }
            if(!RemainingTime.HasValue || RemainingTime == TimeSpan.Zero) {
                timer.Change(-1, -1);
            }
        }
    }
}
<
<
<




|





<



>
>
>
>
>
>
>
|
|
|
|
<
|
|

|
<
<
<
<
<
<
<
<
<
<





|
<


|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<



1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26
27
28










29
30
31
32
33
34

35
36
37







38










using WarshipGirlsRSniffer.Vo;

namespace WarshipGirlsRSniffer.Vm
{
    public class BuildDockVm : VmTimerBase<BuildDockVm>
    {
        private static readonly View.Converter.BuildShipTypeToDescriptionConverter cvt = new View.Converter.BuildShipTypeToDescriptionConverter();

        private BuildDock vo;
        private readonly VmDock dock;


        public BuildDock Vo {
            get { return vo; }
            set
            {
                vo = value;
                endTime = vo.endTime;
                using(SuppressNotification())
                    UpdateTimer(this);

                RaiseMultiPropertyChanged();
            }
        }


        public override ushort Id => vo.id;
        public override bool Locked => vo.locked != 0;
        public BuildShipType ShipType => (BuildShipType)vo.shipType;
        public override string Title => cvt.Convert(ShipType, typeof(string), null, null) as string;











        public BuildDockVm(BuildDock vo, VmDock dock)
        {
            this.vo = vo;
            this.dock = dock;
            endTime = vo.endTime;

            UpdateTimer(this);
        }
    }







}







Changes to WarshipGirlsRSniffer/Vm/CampaignFleetVm.cs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25


26


27
28
29
30
31
32





33



using System.Linq;
using WarshipGirlsRSniffer.Vo;

namespace WarshipGirlsRSniffer.Vm
{
    public class CampaignFleetVm : VmBase<CampaignFleetVm>
    {
        private int[] campaignFleet;
        private int campaignId;

        private readonly VmYard yard;

        public Protocol.Response.Campaign.GetFleet GetFleet {
            set { campaignFleet = value.campaignLevelFleet; campaignId = value.campaign_id; RaiseMultiPropertyChanged(); }
        }

        public Protocol.Response.Campaign.ChangeFleet ChangeFleet {
            set { campaignFleet = value.campaignLevelFleet; campaignId = value.campaign_id; RaiseMultiPropertyChanged(); }
        }

        public int Id => campaignId;
        public ShipStatus Status => ShipStatus.Normal;
        public ShipStatus FleetStatus => Ships.FirstOrDefault(x => x.Status != ShipStatus.Normal)?.Status ?? Status;
        public string Title => (Client.WGRSession.InitTxt.ShipCampaignLevel[campaignId].title ?? $"#{campaignId}") + $"-{Difficulty}";
        public int Difficulty => Client.WGRSession.InitTxt.ShipCampaignLevel[campaignId].difficulty;


        public ShipVm[] Ships => campaignFleet?.Select(x => yard.Ships[x]).ToArray();



        public CampaignFleetVm(VmYard yard)
        {
            this.yard = yard;
        }
    }





}
















|



|



|
|


>
>
|
>
>





|
>
>
>
>
>
|
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using System.Linq;
using WarshipGirlsRSniffer.Vo;

namespace WarshipGirlsRSniffer.Vm
{
    public class CampaignFleetVm : VmBase<CampaignFleetVm>
    {
        private int[] campaignFleet;
        private int campaignId;

        private readonly VmYard yard;

        public Protocol.Response.Campaign.GetFleet GetFleet {
            set { campaignFleet = value.campaignLevelFleet; campaignId = value.campaign_id; _ships = null; RaiseMultiPropertyChanged(); }
        }

        public Protocol.Response.Campaign.ChangeFleet ChangeFleet {
            set { campaignFleet = value.campaignLevelFleet; campaignId = value.campaign_id; _ships = null; RaiseMultiPropertyChanged(); }
        }

        public int Id => campaignId;
        public ShipStatus FleetStatus => ShipStatus.Normal;
        public ShipStatus Status => Ships.FirstOrDefault(x => x.Status != ShipStatus.Normal)?.Status ?? FleetStatus;
        public string Title => (Client.WGRSession.InitTxt.ShipCampaignLevel[campaignId].title ?? $"#{campaignId}") + $"-{Difficulty}";
        public int Difficulty => Client.WGRSession.InitTxt.ShipCampaignLevel[campaignId].difficulty;

        private ShipVm[] _ships;
        public ShipVm[] Ships => _ships ?? (_ships = campaignFleet?.Select(x => yard.Ships[x]).ToArray());

        public RepairDockVm SlowestRepair => yard.Session.Dock.RepairDock.Where(x => x.EndTime.HasValue && campaignFleet.Contains(x.Vo.shipId)).OrderByDescending(x => x.EndTime.Value).FirstOrDefault();

        public CampaignFleetVm(VmYard yard)
        {
            this.yard = yard;
        }

        internal void UpdateShip(int shipId)
        {
            if(campaignFleet.Contains(shipId)) {
                RaisePropertyChanged(nameof(Status));
                RaisePropertyChanged(nameof(SlowestRepair));
            }
        }
    }
}

Changes to WarshipGirlsRSniffer/Vm/EquipmentDockVm.cs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

18

19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34





35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using Linnaea.Extensions;
using System;
using System.Threading;
using WarshipGirlsRSniffer.Vo;

namespace WarshipGirlsRSniffer.Vm
{
    public class EquipmentDockVm : VmBase<RepairDockVm>
    {
        private EquipmentDock vo;
        private readonly VmDock dock;
        private readonly Timer timer;

        public EquipmentDock Vo {
            get { return vo; }
            set { vo = value; RaiseMultiPropertyChanged(); UpdateTimer(this); }
        }



        private DateTimeOffset? _endTime;

        public DateTimeOffset? EndTime => _endTime;
        public byte Id => vo.id;
        public bool Locked => vo.locked != 0;
        public string Title => Equipment.title;
        public ShipEquipment Equipment => Client.WGRSession.InitTxt.ShipEquipment[vo.equipmentCid];
        public TimeSpan? RemainingTime {
            get
            {
                if(_endTime == null) {
                    return null;
                }
                var delta = _endTime.Value - DateTimeOffset.Now;
                return delta.Ticks < 0 ? TimeSpan.Zero : delta;
            }
        }






        public EquipmentDockVm(EquipmentDock vo, VmDock dock)
        {
            this.vo = vo;
            this.dock = dock;

            timer = new Timer(UpdateTimer, null, -1, -1);
            UpdateTimer(this);
        }

        private void UpdateTimer(object _)
        {
            RaisePropertyChanged(nameof(RemainingTime));
            if(_ != null) {
                _endTime = vo.endTime == 0 ? (DateTimeOffset?)null : DateTimeOffsetEx.FromUnixTimeSeconds(vo.endTime);
                if(RemainingTime.HasValue && RemainingTime != TimeSpan.Zero) {
                    timer.Change(1000, 1000);
                }
            }
            if(!RemainingTime.HasValue || RemainingTime == TimeSpan.Zero) {
                timer.Change(-1, -1);
            }
        }
    }
}
<
<
<




|



<



<
<
>
|
>
|
>
|
<
<
<
<
<
<
|
<
|
|
<
<
|
|
>
>
>
>
>





|
<


|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<



1
2
3
4
5
6
7
8

9
10
11


12
13
14
15
16
17






18

19
20


21
22
23
24
25
26
27
28
29
30
31
32
33

34
35
36







37










using WarshipGirlsRSniffer.Vo;

namespace WarshipGirlsRSniffer.Vm
{
    public class EquipmentDockVm : VmTimerBase<RepairDockVm>
    {
        private EquipmentDock vo;
        private readonly VmDock dock;


        public EquipmentDock Vo {
            get { return vo; }


            set
            {
                vo = value;
                endTime = vo.endTime;
                using(SuppressNotification())
                    UpdateTimer(this);








                RaiseMultiPropertyChanged();
            }


        }

        public override ushort Id => vo.id;
        public override bool Locked => vo.locked != 0;
        public override string Title => vo.equipmentCid == 0 ? null : Equipment.title ?? $"#{vo.equipmentCid}";

        public ShipEquipment Equipment => Client.WGRSession.InitTxt.ShipEquipment[vo.equipmentCid];

        public EquipmentDockVm(EquipmentDock vo, VmDock dock)
        {
            this.vo = vo;
            this.dock = dock;
            endTime = vo.endTime;

            UpdateTimer(this);
        }
    }







}







Changes to WarshipGirlsRSniffer/Vm/FleetVm.cs.

10
11
12
13
14
15
16
17
18
19
20
21
22
23



24
25
26
27
28
29




30



        public Fleet Vo {
            get { return vo; }
            set { vo = value; _ships = null;  RaiseMultiPropertyChanged(); }
        }

        public int Id => vo.id;
        public ShipStatus Status => (ShipStatus)vo.status;
        public ShipStatus FleetStatus => Status == ShipStatus.Normal ? (Ships?.FirstOrDefault(x => x?.Status != ShipStatus.Normal)?.Status ?? Status) : Status;
        public string Title => vo.title;

        private ShipVm[] _ships;
        public ShipVm[] Ships => _ships ?? (_ships = vo.ships?.Select(x => yard.Ships[x]).ToArray());




        public FleetVm(Fleet vo, VmYard yard)
        {
            this.vo = vo;
            this.yard = yard;
        }
    }




}









|
|





>
>
>





|
>
>
>
>
|
>
>
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

        public Fleet Vo {
            get { return vo; }
            set { vo = value; _ships = null;  RaiseMultiPropertyChanged(); }
        }

        public int Id => vo.id;
        public ShipStatus FleetStatus => (ShipStatus)vo.status;
        public ShipStatus Status => FleetStatus == ShipStatus.Normal ? (Ships?.FirstOrDefault(x => x?.Status != ShipStatus.Normal)?.Status ?? ShipStatus.Normal) : FleetStatus;
        public string Title => vo.title;

        private ShipVm[] _ships;
        public ShipVm[] Ships => _ships ?? (_ships = vo.ships?.Select(x => yard.Ships[x]).ToArray());

        public RepairDockVm SlowestRepair => yard.Session.Dock.RepairDock.Where(x => x.EndTime.HasValue && vo.ships.Contains(x.Vo.shipId)).OrderByDescending(x => x.EndTime.Value).FirstOrDefault();
        public PveExploreVm Explore => yard.Session.Pve.Explores.FirstOrDefault(x => ReferenceEquals(this, x.Fleet));

        public FleetVm(Fleet vo, VmYard yard)
        {
            this.vo = vo;
            this.yard = yard;
        }

        internal void UpdateShip()
        {
            RaisePropertyChanged(nameof(Status));
            RaisePropertyChanged(nameof(SlowestRepair));
        }
    }
}

Changes to WarshipGirlsRSniffer/Vm/RepairDockVm.cs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

18

19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34





35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using Linnaea.Extensions;
using System;
using System.Threading;
using WarshipGirlsRSniffer.Vo;

namespace WarshipGirlsRSniffer.Vm
{
    public class RepairDockVm : VmBase<RepairDockVm>
    {
        private RepairDock vo;
        private readonly VmDock dock;
        private readonly Timer timer;

        public RepairDock Vo {
            get { return vo; }
            set { vo = value; RaiseMultiPropertyChanged(); UpdateTimer(this); }
        }



        private DateTimeOffset? _endTime;

        public DateTimeOffset? EndTime => _endTime;
        public byte Id => vo.id;
        public bool Locked => vo.locked != 0;
        public string Title => Ship == null ? null : $"{Ship.Name} Lv.{Ship.Level}";
        public ShipVm Ship => dock.Session.Yard.Ships[vo.shipId];
        public TimeSpan? RemainingTime {
            get
            {
                if(_endTime == null) {
                    return null;
                }
                var delta = _endTime.Value - DateTimeOffset.Now;
                return delta.Ticks < 0 ? TimeSpan.Zero : delta;
            }
        }






        public RepairDockVm(RepairDock vo, VmDock dock)
        {
            this.vo = vo;
            this.dock = dock;

            timer = new Timer(UpdateTimer, null, -1, -1);
            UpdateTimer(this);
        }

        private void UpdateTimer(object _)
        {
            RaisePropertyChanged(nameof(RemainingTime));
            if(_ != null) {
                _endTime = vo.endTime == 0 ? (DateTimeOffset?)null : DateTimeOffsetEx.FromUnixTimeSeconds(vo.endTime);
                if(RemainingTime.HasValue && RemainingTime != TimeSpan.Zero) {
                    timer.Change(1000, 1000);
                }
            }
            if(!RemainingTime.HasValue || RemainingTime == TimeSpan.Zero) {
                timer.Change(-1, -1);
            }
        }
    }
}
<
<
<




|



<



<
<
>
|
>
|
>
|
<
<
<
<
<
<
|
<
|
|
<
<
|
|
>
>
>
>
>





|
<


|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<



1
2
3
4
5
6
7
8

9
10
11


12
13
14
15
16
17






18

19
20


21
22
23
24
25
26
27
28
29
30
31
32
33

34
35
36







37










using WarshipGirlsRSniffer.Vo;

namespace WarshipGirlsRSniffer.Vm
{
    public class RepairDockVm : VmTimerBase<RepairDockVm>
    {
        private RepairDock vo;
        private readonly VmDock dock;


        public RepairDock Vo {
            get { return vo; }


            set
            {
                vo = value;
                endTime = vo.endTime;
                using(SuppressNotification())
                    UpdateTimer(this);








                RaiseMultiPropertyChanged();
            }


        }

        public override ushort Id => vo.id;
        public override bool Locked => vo.locked != 0;
        public override string Title => vo.shipId == 0 ? null : Ship == null ? $"#{vo.shipId}" : $"{Ship.Name} Lv.{Ship.Level}";

        public ShipVm Ship => dock.Session.Yard.Ships[vo.shipId];

        public RepairDockVm(RepairDock vo, VmDock dock)
        {
            this.vo = vo;
            this.dock = dock;
            endTime = vo.endTime;

            UpdateTimer(this);
        }
    }







}







Changes to WarshipGirlsRSniffer/Vm/ShipVm.cs.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    public class ShipVm : VmBase<ShipVm>
    {
        private UserShip vo;
        private readonly VmYard yard;

        public UserShip Vo {
            get { return vo; }
            set { vo = value; _equipments = null; RaiseMultiPropertyChanged(); }
        }

        public int Id => vo.id;
        public int Exp => vo.exp;
        public int Cid => vo.shipCid;
        public int Level => vo.level;
        public int NextExp => vo.nextExp;







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    public class ShipVm : VmBase<ShipVm>
    {
        private UserShip vo;
        private readonly VmYard yard;

        public UserShip Vo {
            get { return vo; }
            set { vo = value; _equipments = null; RaiseMultiPropertyChanged(); Fleet?.UpdateShip(); }
        }

        public int Id => vo.id;
        public int Exp => vo.exp;
        public int Cid => vo.shipCid;
        public int Level => vo.level;
        public int NextExp => vo.nextExp;

Changes to WarshipGirlsRSniffer/Vm/VmSession.cs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24

25
26
27
using System.Reactive.Disposables;

namespace WarshipGirlsRSniffer.Vm
{
    public class VmSession : VmBase<VmSession>
    {
        private CompositeDisposable _disposable = new CompositeDisposable();

        public Client.WGRSession Session { get; }

        public string Host => Session.Id.Host;

        public int Uid => Session.Id.Uid;

        public VmYard Yard { get; }
        public VmUser User { get; }
        public VmDock Dock { get; }


        public VmSession(Client.WGRSession sess)
        {
            Session = sess;
            User = new VmUser(this);
            Yard = new VmYard(this);
            Dock = new VmDock(this);

        }
    }
}
<
<




<
<









>







>





1
2
3
4


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25


namespace WarshipGirlsRSniffer.Vm
{
    public class VmSession : VmBase<VmSession>
    {


        public Client.WGRSession Session { get; }

        public string Host => Session.Id.Host;

        public int Uid => Session.Id.Uid;

        public VmYard Yard { get; }
        public VmUser User { get; }
        public VmDock Dock { get; }
        public VmPve Pve { get; }

        public VmSession(Client.WGRSession sess)
        {
            Session = sess;
            User = new VmUser(this);
            Yard = new VmYard(this);
            Dock = new VmDock(this);
            Pve = new VmPve(this);
        }
    }
}

Changes to WarshipGirlsRSniffer/Vm/VmYard.cs.

9
10
11
12
13
14
15

16
17
18

19
20
21
22
23
24
25
    {
        private CompositeDisposable _disposable = new CompositeDisposable();

        public DefaultTable<ShipVm> Ships { get; } = new DefaultTable<ShipVm>();
        public DefaultTable<EquipmentVm> Equipments { get; } = new DefaultTable<EquipmentVm>();
        public DefaultTable<FleetVm> Fleets { get; } = new DefaultTable<FleetVm>();
        public DefaultTable<CampaignFleetVm> CampaignFleets { get; } = new DefaultTable<CampaignFleetVm>();


        public VmYard(VmSession _)
        {

            _disposable.Add(_.Session.Api_Api_InitGame.Subscribe(OnGameInit));

            _disposable.Add(_.Session.Api_Boat_ChangeEquipment.Subscribe(p => UpdateShip(p.Item2.shipVO)));
            _disposable.Add(_.Session.Api_Boat_RemoveEquipment.Subscribe(p => UpdateShip(p.Item2.shipVO)));
            _disposable.Add(_.Session.Api_Boat_Repair.Subscribe(p => UpdateShip(p.Item2.shipVO)));
            _disposable.Add(_.Session.Api_Boat_RepairComplete.Subscribe(p => { if(p.Item2.status != 0) UpdateShip(p.Item2.shipVO); }));
            _disposable.Add(_.Session.Api_Boat_Strengthen.Subscribe(p => UpdateShip(p.Item2.shipVO)));







>



>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    {
        private CompositeDisposable _disposable = new CompositeDisposable();

        public DefaultTable<ShipVm> Ships { get; } = new DefaultTable<ShipVm>();
        public DefaultTable<EquipmentVm> Equipments { get; } = new DefaultTable<EquipmentVm>();
        public DefaultTable<FleetVm> Fleets { get; } = new DefaultTable<FleetVm>();
        public DefaultTable<CampaignFleetVm> CampaignFleets { get; } = new DefaultTable<CampaignFleetVm>();
        public readonly VmSession Session;

        public VmYard(VmSession _)
        {
            Session = _;
            _disposable.Add(_.Session.Api_Api_InitGame.Subscribe(OnGameInit));

            _disposable.Add(_.Session.Api_Boat_ChangeEquipment.Subscribe(p => UpdateShip(p.Item2.shipVO)));
            _disposable.Add(_.Session.Api_Boat_RemoveEquipment.Subscribe(p => UpdateShip(p.Item2.shipVO)));
            _disposable.Add(_.Session.Api_Boat_Repair.Subscribe(p => UpdateShip(p.Item2.shipVO)));
            _disposable.Add(_.Session.Api_Boat_RepairComplete.Subscribe(p => { if(p.Item2.status != 0) UpdateShip(p.Item2.shipVO); }));
            _disposable.Add(_.Session.Api_Boat_Strengthen.Subscribe(p => UpdateShip(p.Item2.shipVO)));
91
92
93
94
95
96
97


98
99
100
101
102
103
104
                if(Equipments.ContainsKey(cid)) return;

                App.BeginDispatcherInvoke(() => {
                    if(Equipments.ContainsKey(cid)) return;
                    Equipments[cid] = new EquipmentVm(new Vo.Equipment() { equipmentCid = cid, uid = vo.uid }, this);
                });
            });


        }

        private void UpdateFleet(Vo.Fleet vo)
        {
            var fleet = Fleets[vo.id];
            if(fleet != null) {
                fleet.Vo = vo;







>
>







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
                if(Equipments.ContainsKey(cid)) return;

                App.BeginDispatcherInvoke(() => {
                    if(Equipments.ContainsKey(cid)) return;
                    Equipments[cid] = new EquipmentVm(new Vo.Equipment() { equipmentCid = cid, uid = vo.uid }, this);
                });
            });

            CampaignFleets.ForEach(x => x.UpdateShip(vo.id));
        }

        private void UpdateFleet(Vo.Fleet vo)
        {
            var fleet = Fleets[vo.id];
            if(fleet != null) {
                fleet.Vo = vo;

Changes to WarshipGirlsRSniffer/Vo/PveExploreVo.cs.

73
74
75
76
77
78
79


80
81
82
83
84
85
86
87
88
    [JsonObject] public struct UserPveLevel
    {
        public int id, uid, status, hp, support_level, support_status, support_oil, support_ammo, support_aluminium, pveLevelId;
    }

    [JsonObject] public struct PveExploreLevel
    {


        public int exploreId, fleetId, startTime, endTime;
    }

    [JsonObject] public struct UserPveExplore
    {
        public PveExploreLevel[] levels;
        public int[] chapters;
    }
}







>
>
|








73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    [JsonObject] public struct UserPveLevel
    {
        public int id, uid, status, hp, support_level, support_status, support_oil, support_ammo, support_aluminium, pveLevelId;
    }

    [JsonObject] public struct PveExploreLevel
    {
        public ushort exploreId;
        public byte fleetId;
        public int startTime, endTime;
    }

    [JsonObject] public struct UserPveExplore
    {
        public PveExploreLevel[] levels;
        public int[] chapters;
    }
}

Changes to WarshipGirlsRSniffer/WarshipGirlsRSniffer.csproj.

222
223
224
225
226
227
228

229
230


231
232
233
234
235
236
237
      <DependentUpon>Fleets.xaml</DependentUpon>
    </Compile>
    <Compile Include="View\Ships.xaml.cs">
      <DependentUpon>Ships.xaml</DependentUpon>
    </Compile>
    <Compile Include="Vm\EquipmentDockVm.cs" />
    <Compile Include="Vm\CampaignFleetVm.cs" />

    <Compile Include="Vm\VmDock.cs" />
    <Compile Include="Vm\FleetVm.cs" />


    <Compile Include="Vm\VmUser.cs" />
    <Compile Include="Vo\CampaignVo.cs" />
    <Compile Include="Vo\Constants.cs" />
    <Compile Include="Vo\DockVo.cs" />
    <Compile Include="Vo\EnemyVo.cs" />
    <Compile Include="Vo\FriendVo.cs" />
    <Compile Include="Vo\MarketingDataVo.cs" />







>


>
>







222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
      <DependentUpon>Fleets.xaml</DependentUpon>
    </Compile>
    <Compile Include="View\Ships.xaml.cs">
      <DependentUpon>Ships.xaml</DependentUpon>
    </Compile>
    <Compile Include="Vm\EquipmentDockVm.cs" />
    <Compile Include="Vm\CampaignFleetVm.cs" />
    <Compile Include="Vm\PveExploreVm.cs" />
    <Compile Include="Vm\VmDock.cs" />
    <Compile Include="Vm\FleetVm.cs" />
    <Compile Include="Vm\VmPve.cs" />
    <Compile Include="Vm\VmTimerBase.cs" />
    <Compile Include="Vm\VmUser.cs" />
    <Compile Include="Vo\CampaignVo.cs" />
    <Compile Include="Vo\Constants.cs" />
    <Compile Include="Vo\DockVo.cs" />
    <Compile Include="Vo\EnemyVo.cs" />
    <Compile Include="Vo\FriendVo.cs" />
    <Compile Include="Vo\MarketingDataVo.cs" />